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

1 ... 262 263 264 [ 265 ] 266 267 268 ... 395


template <class Type> class Queue { public:

Queue(); private:

...

template <class Type> inline Queue<Type>::

eue( ) { front = back = 0; }

За первым вхождением Queue (перед оператором ) следует список параметров, показывающий, какому шаблону принадлежит данная функция-член. Второе вхождение Queue в определение конструктора (после оператора :: ) содержит имя функции-члена, за которым может следовать список параметров шаблона, хотя это и необязательно. После имени функции идет ее определение;. в нем могут быть ссылки на параметр шаблона Type всюду, где в определении обычной функции использовалось бы имя типа.

Функция-член шаблона класса сама является шаблоном. Стандарт C++ требует, чтобы она конкретизировалась только при вызове либо при взятии ее адреса. (Некоторые более старые компиляторы конкретизируют такие функции одновременно с конкретизацией самого шаблона класса.) При конкретизации функции-члена используется тип того объекта, для которого функция вызвана:

Queue<string> qs;

Объект qs имеет тип Queue<string>. При инициализации объекта этого класса вызывается конструктор Queue<string>. В данном случае аргументом, которым конкретизируется функция-член (конструктор), будет string.

Функция-член шаблона конкретизируется только при реальном использовании в программе (т.е. при вызове или взятии ее адреса). От того, в какой именно момент конкретизируется функция-член, зависит разрешение имен в ее определении (см. раздел 16.11) и объявление ее специализации (см. раздел 16.9).

16.3.1. Функции-члены шаблонов Queue и QueueItem

Чтобы понять, как определяются и используются функции-член: шаблонов классов, продолжим изучение шаблонов Queue и QueueItem:



template <class Type> Queue<Type>::~Queue()

while (! is empty() remove();

вне его. Деструктор Queue опустошает очередь:

template <class Type>

void eue<Type>::add( const Type &val ) {

создать нов объект QueueItem QueueItem<Type> *pt =

new QueueItem<Type>( val );

if ( is empty() )

front = back = pt; else {

back->next = pt; back = pt;

Функция-член Queue<Type>::add() помещает новый элемент в конец очереди:

Функция-член Queue<Type>::remove() возвращает значение элемента, находящегося в начале очереди, и удаляет сам элемент.

template <class Type> class Queue { public:

Queue() : front( 0 ), back ( 0 ) { }

~Queue() ;

Type& remove(); void add( const Type & );

bool is empty() const { return front == 0;

private:

QueueItem<Type> *front; QueueItem<Type> *back;

Деструктор, а также функции-член: remove () и add() определены не в теле шаблона, а



#include <iostream> #include <cstdlib>

template <class Type> Type Queue<Type>::remove() {

if ( is empty() ) {

cerr << remove() вызвана для пустой очереди\n ; exit( -1 );

QueueItem<Type> *pt = front; front = front->next;

Type retval = pt->item;

delete pt;

return retval;

Мы поместили определения функций-членов в заголовочный файл Queue.h, включив его в каждый файл, где возможны конкретизации функций. (Обоснование этого решения, а также рассмотрение более общих вопросов, касающихся модели компиляции шаблонов, mi отложим до раздела 16.8.)

В следующей программе иллюстрируется использование и конкретизация функции-члена

#include <iostream> #include Queue.h

int main()

конкретизируется класс Queue<int>

оператор new требует, чтобы Queue<int> был определен Queue<int> *p qi = new Queue<int>;

int ival;

for ( ival = 0; ival < 10; ++ival )

конкретизируется функция-член add() p qi->add( ival );

int err cnt = 0;

for ( ival = 0; ival < 10; ++ival ) {

конкретизируется функция-член remove() int qval = p qi->remove();

if ( ival != qval ) err cnt++;

if ( !err cnt )

cout << !! queue executed ok\n ; else cerr << ?? eue errors: << err cnt << endl; return 0;

шаблона Queue:

После компиляции и запуска программа выводит следующую строку:



1 ... 262 263 264 [ 265 ] 266 267 268 ... 395

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