240-1677 (Объективное программирование), страница 7
Описание файла
Документ из архива "Объективное программирование", который расположен в категории "". Всё это находится в предмете "информатика" из , которые можно найти в файловом архиве . Не смотря на прямую связь этого архива с , его также можно найти и в других разделах. Архив можно найти в разделе "рефераты, доклады и презентации", в предмете "информатика, программирование" в общих файлах.
Онлайн просмотр документа "240-1677"
Текст 7 страницы из документа "240-1677"
+--------+ ¦L----------¦
base* ¦ ¦
L----------- base
head Строка заголовка БД
--¬ S0
¦-------------->---------¬0 -string---¬
L-- ¦ ------------------>-base---¬¦
base** +--------+ ---------->L--------¦
¦ --------------¬ L--------- +--------+ ¦ ¦ D0
¦ --------- ¦ -dat------¬
+--------+ L--->-base---¬¦
base* ¦L--------¦
L---------//------------------------------------------------------// Меню классов объектов (типов столбцов)
string S0;
dat D0;
time T0;
integer I0;
base *TYPE[] = {
(base*) &S0;
(base*) &D0;
(base*) &T0;
(base*) &I0;
};
//-----------------------------------------------------// Создание структуры БД
#define MAXCOL 30
#define MAXREC 1000
table::table()
{
int i,j,n;
char ss[80];
names = new char*[MAXCOL]; // Таблица адресов имен столбцов
head = new base*[MAXCOL]; // Таблица ссылок на объекты
for (nc=0; nc { // Ввод имени столбца gets(ss); if (strlen(ss)=0) break;// Пустая строка - выход name[nc] = new char[strlen(ss)+1]; //------ построение меню типов элементов БД ... for (j=0; j<3; j++) { gotoxy(10,5+j); cputs( TYPE[j]->NAME() ); } //------ выбор типа столбца - n head[nc] = TYPE[n]; // Ссылка на объект с классом, // соответствующим классу // объектов столбца TBL = new base**[MAXREC]; nr = 0; // Таблица ссылок на строки БД } } //------------------------------------------------------// Деструктор БД tabe::~table() { int i,j; for (i=0; i { for (j=0; j delete TBL[i][j]; // Разрушение объекта i-ой строки // j-го столбца по ссылке на // объект БК // (виртуальный деструктор) delete TBL[i]; } delete TBL; for (j=0; j delete names[j]; } //------------------------------------------------------// Добавление строки к БД void table::append() { int i; TBL[nr] = new base*[nc]; // Создание таблицы ссылок для строки БД for (i=0; i { // заголовка БД TBL[nr][i] = head[i]->COPY(); printf("Столбец %s типа %s :",names[i],head[i]->NAME()); // Вывод подсказки имени и типа столбца while(TBL[nr][i]->GET() ==0);// Ввод значения нового объекта } nr++; } //-------------------------------------------------------// Нахождение среднего арифметического по заданному столбцу long table::averrage(int n) { long r; int i; if (n=nc) return(0); for (r=0, i=0; i return(r / nr); } //-------------------------------------------------------// Сортировка по заданному столбцу методом "пузырька" void table::sort(int n) { int i,k; base *p; do { for (i=0; i< nr-1; i++) // Виртуальная функция сравнения // объектов в соседних строках // n-го столбца if (TBL[i][n]->CMP(TBL[i+1][n]) <0) { p = TBL[i][n]; TBL[i][n] = TBL[i+1][n]; TBL[i+1][n] = p; k++; } } while (k); // Пока есть перестановки } //----------------------------------------------------------// Выбор элемента (i,j) в БД - возвращает неявную ссылку на // БК объекта, по которой возможен вызов любой виртуальной // функции static base empty; // Пустой объект для ошибочного выбора base& table::opertor()(int i,int j) { if (i= nr) return(empty); if (j= nc) return(empty); return (*TBL[i][j]); // Возвратить неявную ссылку на объект } //--------------------------------------------------------// Пример работы с классом РБД void main() { int i,j; table R; // Создание БД for (i=0; i<10; i++) R.append(); // Ввод 10-ти строк R.sort(1); // Сортировка по первому столбцу scanf("%d %d", &i, &j); // Вывод значения элемента R(i,j).PUT(); R(1,2) + "1234"; // Операция "объект + строка" // для элемента 1,2 } Лекция 9. Шаблоны. ----------------- Довольно часто классы создаются для объединения множества элементов данных, которые внутри объекта могут быть связаны массивом ссылок, списком, деревом и т.д.. При этом объект класса содержит ссылки Таким образом, требуется определить некоторое множество идентичных классов с параметризованным типом внутренних элементов. То есть должна быть задана заготовка класса (шаблон), в котором в виде параметра задан тип (класс) входящих в него внутренних элементов данных. Тогда при создании объекта необходимо дополнительно указывать и конкретный тип внутренних элементов в качестве параметра. Создание объекта сопровождается также и созданием соответствующего конкретного класса для заданного конктретного типа. Принятый в Си++ способ определения множества классов с параметризованным внутренним типом данных (иначе, макроопределение) называется шаблоном (template). Синтаксис шаблона рассмотрим на примере шаблона класса векторов, содержащих динамический массив ссылок на переменные заданного типа. --- параметр шаблона - класс "T", внутренний ¦ тип данных ¦ --- имя группы шаблонных классов template class vector { int tsize; // Общее количество элеметов int csize; // Текущее количество элементов T **obj; // Массив ссылок на параметризован // ные объекты типа "T" public: T *operator[](int); // оператор [int] возвращает ссылку // на параметризованный объект // класса "T" void insert(T*); // функция включения объекта типа "T" int extract(T*); // }; Данный шаблон может использоваться для порождения объектов-векторов, каждый из которых хранит объекты определенного типа. Имя класса при этом составляется из имени шаблона "vector" и имени типа данных (класса), который подставляется вместо параметра "Т": vector a; vector b; extern class time; vector c; Заметим, что транслятором при определении каждого вектора с новым типом объектов генерируется описание нового класса по заданному шаблону (естественно, неявно в процессе трансляции): class vector { int tsize; int csize; int **obj; public: int *operator[](int); void insert(int*); int index(int*); }; Далее следует очевидное утверждение, что элементыфункции шаблона также должны быть параметризованы, то есть генерироваться для каждого нового типа данных. Действительно, это так: элементы-функции шаблона классов в свою очередь также являются шаблонными функциями с тем же самым параметром. То же самое касается переопределяемых операторов: --- параметр шаблона - класс "T", внутренний ¦ тип данных ¦ --- имя элемента-функции или ¦ ¦ оператора - параметризовано ¦ ¦ template T* vector::operator[](int n) { if (n >=tsize) return(NULL); return (obj[n]); } template int vector::index(T *pobj) { int n; for (n=0; n if (pobj == obj[n]) return(n); return(-1); } Заметим, что транслятором при определении каждого вектора с новым типом объектов генерируется набор элементовфункций по заданным шаблонам (естественно, неявно в процессе трансляции). При этом сами шаблонные функции должны размещаться в том же заголовочном файле, где размещается определение шаблона самого класса. int* vector::operator[](int n) { if (n >=tsize) return(NULL); return (obj[n]); } int vector::index(int *pobj) { int n; for (n=0; n if (pobj == obj[n]) return(n); return(-1); } Шаблоны могут иметь также и параметры-константы, которые используются для статического определения размерностей внутренних структур данных. Кроме того, шаблон может использоваться для размещения не только ссылок на параметризованные объекты, но и сами объекты. В качестве примера рассмотрим шаблон для построения циклической очереди ограниченного размера для параметризованных объектов. template class FIFO { int fst,lst; // Указатели на начало-конец // очереди T queue[size]; // Массив объектов класса "T" // размерности "size" public: T from(); // Функции включения-исключения void into(T); // FIFO(); // Конструктор }; template FIFO::FIFO() { fst = lst = 0; } template T FIFO::from() { T work; if (fst !=lst) { work = area[lst++]; lst = lst % size; } return(work); } template void FIFO::into(T obj) { area[fst++] = obj; fst = fst % size; } Пример использования: FIFO a; FIFO b; struct x {}; FIFO c; Пример сгенерированного компилятором класса для объекта "a". class FIFO { int fst,lst; double queue[100]; public: double from(); void into(double); FIFO(); }; FIFO::FIFO() { fst = lst = 0; } double FIFO::from() { double work; if (fst !=lst) { work = area[lst++]; lst = lst % 100; } return(work); } void FIFO::into(double obj) { area[fst++] = obj; fst = fst % 100; } 37