Функции-члены шаблонов Queue и QueueItem
Чтобы понять, как определяются и используются функции-члены шаблонов классов, продолжим изучение шаблонов Queue и QueueItem:
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()
определены не в теле шаблона, а вне его. Деструктор Queue
опустошает очередь:
template <class Type> Queue<Type>::~Queue() { while (! is_empty() ) remove(); |
}
Функция-член Queue<Type>::add()
помещает новый элемент в конец очереди:
template <class Type> void Queue<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>::remove()
возвращает значение элемента, находящегося в начале очереди, и удаляет сам элемент.
#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, включив его в каждый файл, где возможны конкретизации функций. (Обоснование этого решения, а также рассмотрение более общих вопросов, касающихся модели компиляции шаблонов, мы отложим до раздела 16.8.)
В следующей программе иллюстрируется использование и конкретизация функции-члена шаблона Queue:
#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 << "?? queue errors: " << err_cnt << endl; return 0; |
}
После компиляции и запуска программа выводит следующую строку:
!! queue executed ok
Упражнение 16.5
Используя шаблон класса Screen, определенный в разделе 16.2, реализуйте функции-члены Screen
(см. разделы 13.3, 13.4 и 13.6) в виде функций-членов шаблона.