Правила программирования на Си и Си++



         

158. Шаблоны не заменяют наследование; они его автоматизируют


Главное, что нужно запомнить о шаблонах классов, — это то, что они порождают много определений классов. Как и всякий раз, когда у вас есть множество сходных определений классов, идентичные функции должны быть соединены в общий базовый класс.

Во-первых, давайте взглянем на то, что не нужно делать. Класс storable, уже использованный мной, снова представляется хорошим примером. Сначала создадим объект collection для управления сохраняемыми объектами:

class collection

{

   storable *head;

public:

// ...

storable *find( const storable &a_match_of_this ) const;

};

storable *collection::find( const storable &a_match_of_this ) const

{

// Послать сообщение объекту начала списка, указывающее, что спи–

// сок просматривается на совпадение со значением a_match_of_this;

   return  head ? head->find( a_match_of_this )

                : NULL

                ;

}

Механизм поиска нужных объектов скрыт внутри класса storable. Вы можете изменить лежащую в основе структуру данных, поменяв определение storable, и эти изменения совсем не затронут реализацию класса collection.

Затем давайте реализуем класс storable, использующий простой связанный список в качестве лежащей в основе структуры данных:

class storable

{

   storable *next, *prev;

public:

   storable *find ( const storable &match_of_this ) const;

   storable *successor ( void ) const;

   virtual int

operator== ( const storable &r ) const;

};

storable *storable::find( const storable &match_of_this ) const

{

// Возвращает указатель на первый элемент в списке (начиная с

// себя), имеющий тот же ключ, что и match_of_this. Обычно,

// объект-коллекция должен послать это сообщение объекту начала

// списка, указатель на который хранится в классе коллекции.

   storable *current = this;

   for( ; current; current = current->next )

      if( *current == match_of_this )   // найдено совпадение

         return current;

}

storable *storable::successor( void ) const




Содержание  Назад  Вперед