С++ для начинающих


Функции-члены шаблонов 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) в виде функций-членов шаблона.


Содержание раздела