Программирование >>  Инициализация объектов класса, структура 

1 ... 268 269 270 [ 271 ] 272 273 274 ... 395


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. Позже, когда встречается реальное



1 ... 268 269 270 [ 271 ] 272 273 274 ... 395

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика