Совет
Используемый повсеместно в данном тексте термин "родовой" (generic) был выбран как наиболее образный. Для строгих формулировок предпочтительнее пользоваться термином "шаблон" (template). Термин "родовой" или "параметризованный" (parameterized) в данном контексте вполне корректен, он просто не является общепринятым.
В этом разделе вместо изучения формального синтаксиса мы рассмотрим несколько примеров. Существенные моменты использования классов-шаблонов в примерах будут снабжены подробными комментариями.
Класс-шаблон для вектора
Шаблон вектора заслуживает того, чтобы включить его в свои актив. Вектор, чаще называемый массивом, является основой для целого ряда структур данных, таких как очереди, стеки и списки. Кроме того, массивы настолько распространены и привычны, что работа с ними обычно не представляет больших сложностей. .
Как определяется массив для базовых типов данных, всем нам хорошо известно: определение начинается с типа данных, далее следует имя массива и в скобках операции индексирования [ ] его размер. Оператор
int intArray[10] ;
определяет целый массив. Как было показано в предыдущих главах, массивы могут быть и левосторонними, и правосторонними аргументами. В векторе это свойство обязательно следует сохранить.
Если превратить целочисленный массив в класс, то его можно будет снабдить различными полезными свойствами, например контролем границ. Применим испытанный прием: определим класс для простого типа данных, а затем его параметризуем (чтобы проиллюстрировать, как это делается).
class INT_VECTOR
{
public: (
INT_VECTOR (unsigned long sz = 10) : size(sz), data(new int [sz+1]) {•};
virtual ~INT_VECTOR() { delete[] data; } ,
int& operator[J( unsigned long index j)
(return j < size ? data[j] : data[sz] /*фиктивное значение*/;} private:
unsigned int size;
int * data; ,
// Блокирование копий и присваивания, поскольку
// копирование структур данных слишком накладно
INT_VECTOR ( const INT_VECTORS) ;
INT_VECTOR& operator" ( const INT_VECTOR &) ;