|
Программирование >> Инициализация объектов класса, структура
template <class Type> class Queue: ... private: class QueueItem { public: QueueItem( Type val ) : item( val ), next( 0 ) { ... } Type item; QueueItem *next; поскольку QueueItem - вложенн тип, а не шаблон, определенна вне Queue, то аргумент шаблона <Type> после QueueItem можно опустить QueueItem *front, *back; ... использовать во вложенном: }; При каждой конкретизации Queue создается также класс QueueItem с подходящим аргументом для Type. Между конкретизациями шаблонов QueueItem и Queue имеется взаимно однозначное соответствие. Вложенный в шаблон класс конкретизируется только в том случае, если он используется в контексте, где требуется полный тип класса. В разделе 16.2 mi упоминали, что конкретизация шаблона класса Queue типом int не означает автоматической конкретизации и класса QueueItem<int>. Члены front и back - это указатели на QueueItem<int>, а если объявлены только указатели на некоторый тип, то конкретизировать соответствующий класс не обязательно, хотя QueueItem вложен в шаблон класса Queue. QueueItem<int> конкретизируется только тогда, когда указатели front или back разыменовываются в функциях-членах класса Queue<int>. Внутри шаблона класса можно также объявлять перечисления и определять типы (с помощью typedef): Альтернативный подход к реализации состоит в том, чтобы вложить определение шаблона класса QueueItem в закрытую секцию шаблона Queue. Поскольку QueueItem является вложенным закрытым типом, он становится недоступным вызывающей программе, и обратиться к нему можно лишь из шаблона класса Queue и его друзей (например, оператора вывода). Если же сделать члены QueueItem открытыми, то объявлять Queue другом QueueItem не понадобится. Семантика исходной реализации при этом сохраняется, но отношение между шаблонами QueueItem и Queue моделируется более элегантно. Поскольку при любой конкретизации шаблона Queue требуется конкретизировать тем же типом и QueueItem, то вложенный класс должен быть шаблоном. Вложенные классы шаблонов сами являются шаблонами классов, а параметры объемлющего шаблона можно int size> template <class Type, class Buffer: public: enum Buf vals { last = size-1, Buf size }; typedef Type BufType; BufType array[ size ]; ... Вместо того чтобы явно включать член Buf size, в шаблоне класса Buffer объявляется перечисление с двумя элементами, которые инициализируются значением параметра шаблона. Например, объявление Buffer<int, 512> small buf; устанавливает Buf size в 512, а last - в 511. Аналогично Buffer<int, 1024> medium buf; устанавливает Buf size в 1024, а last - в 1023. Открытый вложенный тип разрешается использовать и вне определения объемлющего класса. Однако вызывающая программа может ссылаться лишь на конкретизированные экземпляры подобного типа (или элементов вложенного перечисления). В таком случае имени вложенного типа должно предшествовать имя конкретизированного шаблона ошибка: какая конкретизация Buffer? Buffer::Buf vals bfv0; класса: Buffer<int,512>::Buf vals bfv1; правильно Это правило применимо и тогда, когда во вложенном тине не используются параметры включающего шаблона: template <class T> class Q { public: enum QA { empty, full }; не зависит от параметров QA status; ... #include <iostream> int main() { Q<double> qd; Q<int> qi; qd.status = Q::empty; ошибка: какая конкретизация Q? qd.status = Q<double>::empty; правильно int val1 = Q<double>::empty; int val2 = Q<int>::empty; if ( val1 != val2 ) cerr << ошибка реализации! << endl; return 0; Во всех конкретизациях Q значения empty одинаковы, но при ссылке на empty необходимо указывать, какому именно экземпляру Q принадлежит перечисление. Упражнение 16.8 Определите класс List и вложенн1й в него ListItem из раздела 13.10 как шаблоны. Реализуйте аналогичные определения для ассоциированных членов класса. 16.7. Шаблоны-члены Шаблон функции или класса может быть членом обычного класса или шаблона класса. Определение шаблона-члена похоже на определение шаблона: ему предшествует ключевое слово template, за которым идет список параметров:
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |