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



         

Конкретизация шаблона класса - часть 4


Наш класс QueueItem служит вспомогательным средством для реализации класса Queue и не будет непосредственно употребляться в вызывающей программе. Поэтому пользовательская программа способна манипулировать только объектами Queue. Конкретизация шаблона QueueItem происходит лишь в момент конкретизации шаблона класса Queue или его членов. (В следующих разделах мы рассмотрим конкретизации членов шаблона класса.)

В зависимости от типов, которыми может конкретизироваться шаблон, при его определении надо учитывать некоторые нюансы. Почему, например, следующее определение конструктора класса QueueItem не подходит для конкретизации общего вида?

template <class Type>

class QueueItem {

public:

   QueueItem( Type );   // неудачное проектное решение

   // ...

};

В данном определении аргумент передается по значению. Это допустимо, если QueueItem конкретизируется встроенным типом (например, QueueItem<int>). Но если такая конкретизация производится для объемного типа (скажем, Matrix), то накладные расходы, вызванные неправильным выбором на этапе проектирования, становятся неприемлемыми. (В разделе 7.3 обсуждались вопросы производительности, связанные с передачей параметров по значению и по ссылке.) Поэтому аргумент конструктора объявляется как ссылка на константный тип:

QueueItem( const Type & );

Следующее определение приемлемо, если у типа, для которого конкретизируется QueueItem, нет ассоциированного конструктора:

template <class Type>

class QueueItem {

   // ...

public:

   // потенциально неэффективно

   QueueItem( const Type &t ) {

      item = t; next = 0;

   }

};

Если аргументом шаблона является тип класса с конструктором (например, string), то item инициализируется дважды! Конструктор по умолчанию string вызывается для инициализации item перед выполнением тела конструктора QueueItem. Затем для созданного объекта item производится почленное присваивание. Избежать такого можно с помощью явной инициализации item в списке инициализации членов внутри определения конструктора QueueItem:

template <class Type>

class QueueItem {

   // ...

public:

   // item инициализируется в списке инициализации членов конструктора

   QueueItem( const Type &t )

            : item(t) { next = 0; }

};

(Списки инициализации членов и основания для их применения обсуждались в разделе 14.5.)




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