|
Программирование >> Решение нетривиальных задач
для того, чтобы получить 20-элементный массив из 10-элементных массивов. 157. Шаблоны классов должны обычно определять производные классы 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; В действительности я бы использовал множественное наследование с участием класса string. Использованный здесь код имеет цель немного упростить пример. 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 Возвращает следующее значение в последовательности. return next; Функция operator==() должна быть чисто виртуальной, потому что отсутствует возможность ее реализации на уровне класса storable. Реализация должна быть выполнена в производном классе13 : class storable string : public storable string s; public: virtual int operator==( const storable &r ) const; ... virtual int operator==( const storable &r ) const storable string *right = dynamic cast<storable string *>( &r return right ? (s == r.s) : NULL; Я здесь использовал предложенный в ISO/ANSI Си++ безопасный механизм нисходящего приведения типов. right инициализируется значением null, если передаваемый объект (r) не относится к типу См. пред1дущее примечание к правилу 156. - Ред. storable string. Например, он может принадлежать к некоторому другому классу, также являющемуся наследником storable. Пока все идет хорошо. Теперь к проблемам, связанным с шаблонами. Кто-нибудь, не понимающий того, что делает, говорит: Ребята, я могу исключить наследование и потребность в виртуальных функциях, используя шаблоны , а делает, вероятно, нечто подобное: template <class t key> class storable storable *next, *prev; t key key; public: ... storable *find ( const storable &match me ) const; storable *successor ( void ) const; int operator==( const storable &r ) const; template <class t key> int storable<t key>::operator==( const storable<t key> &r ) const return key == r.key ; template <class t key> storable<t key> *storable<t key>::successor( void ) const return next; template <class t key> storable *storable<t key>::find( const storable<t key> &match me ) const storable<t key> *current = this; for( ; current; current = current->next ) if( *current == match me ) найдено совпадение return current; Проблема здесь в непроизводительных затратах. Функции-члены шаблона класса сами являются шаблонами функций. Когда компилятор расширяет шаблон storable, он также расширяет варианты всех функций-членов этого шаблона*. Хотя я их не показал, вероятно, в классе storable
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |