C++ Программирование в среде С++ Builder 5

         

Создание представителей шаблона


Чтобы создать из шаблона представитель конкретного класса, нужно конструировать объект, указав для его типа имя шаблона с набором конкретных аргументов (типов и констант). Каждый формальный тип в списке параметров шаблона нужно заменить на имя действительного типа. Каждая формальная константа заменяется на константу указанного в шаблоне типа:

// Шаблон класса. template <ciass T, int О class TmplClass { ... };

// Создание представителей шаблонных классов.

TmplClass<long, 100> IClassObj;

TmplClass<float, 40> *fClassPtr;

fClassPtr = new TmplClass<float, 40>;

После того, как представитель шаблонного класса создан, с ним можно обращаться точно так же, как с любым объектом, принадлежащим к обыч-

ному классу. Ниже показан пример программы, использующей определение шаблона из листинга 10.2.

Листинг 10.3. Создание и использование представителя шаблонного класса

///////////////////////////////////////////////

// Usetmpl.cpp: Использование шаблона класса. //

#include <iostream.h>

#pragma hdrstop

#include <condefs.h>



#include "Deftmpl.h"

// Включить определение шаблона.

// Класс записей, для которого будет создан шаблонный класс. class Record {

char str[41] ;

public:

Record(void) { str[0] = 0; }

void Set(const char *s)

{ strncpy(str, s, 40);}

char *Get(void)

{ return str; } };

#pragma argsused

int main(int argc, char* argv[])

{

const int NumRec = 4;

DataBase<Record, NumRec> db; // Объявление объекта

// с 4-мя записями.

// Инициализация массива.

db.RecO .Set("First string.");

db.Rec().Set("Second string.");

db.RecO .Set("Third string.");

db.Rec().Set("Fourth string.");

cout.setf(ios::boolalpha);

// Чтение с попыткой выхода за пределы массива.

db.Rec(O); // Позиционирование на 0.

for (int i=0; i<=NumRec; i++) {

cout << db.RecO .Get() << " Error: ";

cout << db.Error() << endl;

} cout << endl;

// Чтение с прямым указанием индекса.


for (int i=NumRec-l; i>-l; i--) {

cout << db.Rec(i).Get() << " Error: ";

cout << db.Error() << endl;

}

return 0;

}

Вывод программы показан на рис. 10.2.

В начале файла программы находится определение класса Record, который используется как аргумент шаблона DataBase. Это класс строк с конструктором по умолчанию и операциями чтения-записи содержимого строки.

Программа создает представитель шаблонного класса DataBase< Record, 4> и выполняет над ним различные действия — запись строк в “поток”, позиционирование, чтение.



Рис. 10.2 Программа UsetmpI



Когда при обработке исходного файла компилятору встречается создание объекта на основе некоторого шаблона класса, он прежде всего генерирует представитель шаблона, или шаблонный класс, как мы его назвали. По существу при этом генерируется и компилируется код всех функций-элементов шаблона для данного набора его аргументов (и код некоторых вспомогательных функций). После этого компилятор может конструировать объект шаблонного класса, вызывать нужные функции-элементы объекта и т. д.

Если создается шаблонный объект, аргументы которого совпадают с аргументами объекта, ранее созданного в текущем модуле компиляции, то новый представитель шаблона не генерируется. Данный шаблонный класс уже существует, остается только конструировать объект.

Для удобства работы с шаблонными классами можно воспользоваться определением typedef, например:



template<class T> TmplClass { ... };

typedef TmplClass<int> IClass;

IClass iCIassObj; IClass *iCiassPtr; iCIassPtr = new IClass;


Содержание раздела