    На этой стадии настоящая природа Т еще не известна, поэтому в программе 
его можно использовать только в самых общих случаях. Тем не менее, конструктор 
TDatabase в строках 12-13 выделяет память для массива объектов Т, присваивая адрес 
массива указателю гр и заодно устанавливая член num равным требуемому числу 
записей. (Для простоты в классе игнорируются все связанные с выделением памяти 
ошибки, которые могут возникнуть.) В строке 15 этот массив удаляется с помощью 
оператора специального вида delete[] с целью обеспечения вызова деструктора для 
массива, содержащего объекты класса. 
    В строке 17 объявляется функция-член GetRecord(), возвращающая ссылку на 
объект типа Т, идентифицируемый номером записи recnum. Это еще один вид 
обобщенной операции, не требующей знания определенного типа Т. 
    Функции-члены шаблонного класса могут реализоваться встраиваемыми, как это 
показано на примере конструктора и деструктора класса TDatabase. Или же они могут 
реализоваться отдельно. Конечно, поскольку эти функции-члены шаблонного класса 
пока остаются только объявлениями, их вполне можно поместить в заголовочный 
файл, а не в отдельный модуль. Функция DoNothingO, которая, как подсказывает 
ее имя, не выполняет никаких действий, демонстрирует общий вид реализации 
функций-членов шаблонного класса: 

    template<class T> 
    void TDatabase<T>::DoNothing(void) 

    Заголовок функции-члена предварен фразой template<class Т>. Затем следует 
тип возвращаемого функцией значения (void), имя класса (TDatabase<T>) и 
оператор разрешения области видимости (::). Последним идет объявление самой 
функции (DoNothing(void)) и тело (пустое, в данном случае). Используйте этот 
пример как образец для написания ваших собственных функций-членов шаблонных классов. 
    В строках 25-33 демонстрируется более сложный пример функции-члена 
шаблонного класса вместе с операторами, реализующими действия функции. Функция 
GetRecord() возвращает ссылку на объект типа Т. Внутри функции указатель сгр типа Т 
присваивается указателю того же типа с именем гр. Иными словами, указатель 
сгр ссылается на первую запись, сохраненную в объекте класса TDatabase. В 
строке 29 проверяется, соответствует ли параметр recnum допустимому диапазону 
значений. Если да, цикл while в строках 30-31 декрементирует  параметр recnum 
до нуля и одновременно передвигает указатель сгр на одну запись в базе данных. 
    Обратите внимание на строку 31. Инкрементирование указателя р с помощью 
выражения р++ сдвигает указатель на число байтов объекта, на который 
ссылается р. В классе Database даже несмотря на то, что тип объекта, на 
который ссылается сгр, не известен, вполне приемлемо выражение сгр++. Позже, 
когда будет задан действительный тип для шаблона класса, компилятор сможет 
сгенерировать соответствующие инструкции для увеличения указателя сгр на 
величину sizeof(T). Без шаблонных классов подобные обобщенные операторы было 
бы не так-то легко написать. 
    В строке 32 возвращается разыменованное значение указателя сгр — другими 
словами, ссылка на любой объект, адресуемый сгр. Это завершает объявление 
шаблона класса, в котором не делается никаких предположений о том, какого типа 
данные в нем запоминаются. 
    Следующий шаг — использование шаблона для создания объекта класса базы 
данных, способного запомнить некоторое число записей. В листинге 15.13 
демонстрируется работа шаблона класса TDatabase. 

    Листинг 15.13. CTEMPLAT.CPP (использование шаблонов класса) 

    1:	#include <iostream.h> 
    2:	#include <string.h> 
    3:	#include "db.h"   
    4:	
    5:	class TRecord {    
    6:	private: 
    7:	   char name[41];                                                          
    6:	public:	
    9:	  TRecord()
    10:	    { nameCO] = 0;  }	
    11:	 Tfiecord(const char *s)	
    12:	    { Assign(s);  }             
    13:	 void Assign(const char *s)                     
    14:	    { strncpy(name,  s, 40);  }     
    15:	 char *GetName(void)	
    16:	    { return name;  }	
    17: 
    18:	
    19:	main()      
    20:	{                    
    21:	  int rn;                                      // Индекс числа записей	
    22:	 TDatabase<TRecord> db(3);       // База данных из трех TRecords	


    392     Часть III. Программирование на ANSI C++ 
