|
Программирование >> Инициализация объектов класса, структура
template <class T> class Queue { ... public: шаблон-член конструктора template <class Iter> Queue( Iter first, Iter last ) : front( 0 ), back( 0 ) for ( ; first != last; ++first ) add( * first ); Такой конструктор позволяет инициализировать очередь содержимым другого контейнера. У контейнерных типов из стандартной библиотеки C++ также есть предназначенные для этой цели конструкторы в виде шаблонов-членов. Кстати, в первом (в данном разделе) определении функции main() использовался конструктор-шаблон для вектора: vector<int> vi( ai, ai + 4 ); Это определение конкретизирует шаблон конструктора для контейнера vector<int> типом int*, что позволяет инициализировать вектор содержимым массива элементов типа int. Шаблон-член, как и обычные члены, может быть определен вне определения объемлющего класса или шаблона класса. Так, являющиеся членами шаблон класса CL или шаблон функции assign() могут быть следующим образом определены вне шаблона Queue: template <class T> class Queue { private: template <class Type> class CL; ... public: template <class Iter> void assign( Iter first, Iter last ); ... template <class T> template <class Type> class Queue<T>::CL<Type> Type member; T mem; template <class T> template <class Iter> void Queue<T>::assign( Iter first, Iter last ) while ( ! is empty() ) remove(); for ( ; first != last; ++first ) add( *first ); Определению шаблона-члена, которое находится вне определения объемлющего шаблона класса, предшествует список параметров объемлющего шаблона класса, а за ним должен следовать собственный такой список. Вот почему определение шаблона функции assign() (члена шаблона класса Queue) начинается с template <class T> template <class Iter> Первый список параметров шаблона template <class T> относится к шаблону класса Queue. Второй - к самому шаблону-члену assign(). Имена параметров не обязаны совпадать с теми, которые указаны внутри определения объемлющего шаблона класса. Приведенная инструкция по-прежнему определяет шаблон-член assign() : void Queue<TT>::assign( IterType first, IterType last ) template <class TT> template <class IterType> 16.8. Шаблоны классов и модель компиляции A Определение шаблона класса - это лишь предписание для построения бесконечного множества типов классов. Сам по себе шаблон не определяет никакого класса. Например, когда компилятор видит: int main() { Queue<int> *p qi = new Queue<int>; использование класса, конкретизированного по шаблону, скажем: компилятор конкретизирует тип класса Queue<int>, применяя сохраненное внутреннее представление определения шаблона Queue. Шаблон конкретизируется только тогда, когда он употребляется в контексте, требующем полного определения класса. (Этот вопрос подробно обсуждался в разделе 16.2.) В примере выше класс Queue<int> конкретизируется, потому что компилятор должен знать размер типа Queue<int>, чтобы выделить нужный объем памяти для объекта, созданного оператором new. Компилятор может конкретизировать шаблон только тогда, когда он видел не только его объявление, но и фактическое определение, которое должно предшествовать тому месту объявление шаблона класса template <class Type> class Queue; Queue<int>* global pi = 0; правильно: определение класса не нужно int main() { ошибка: необходима конкретизация определение шаблона класса должно быть видимо Queue<int> *p qi = new Queue<int>; программы, где этот шаблон используется: Шаблон класса можно конкретизировать одним и тем же типом в нескольких файлах. Как и в случае с типами классов, когда определение класса должно присутствовать в каждом файле, где используются его члены, компилятор конкретизирует шаблон некоторым типом во всех файлах, в которых данный экземпляр употребляется в контексте, требующем полного определения класса. Чтобы определение шаблона было доступно везде, где может понадобиться конкретизация, его следует поместить в заголовочный файл. Функции-члены и статические данные-члены шаблонов классов, а также вложенные в них типы ведут себя почти так же, как сами шаблоны. Определения членов шаблона используются для порождения экземпляров членов в конкретизированном шаблоне. Если компилятор видит: template <class Type> class Queue { ... }; он только сохраняет внутреннее представление Queue. Позже, когда встречается реальное
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |