Программирование >>  Инициализация объектов класса, структура 

1 ... 260 261 262 [ 263 ] 264 265 266 ... 395


template <class Type> class QueueItem {

...

public:

потенциально неэффективно QueueItem( const Type &t ) { item = t; next = 0;

QueueItem, нет ассоциированного конструктора:

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

template <class Type> class QueueItem {

...

public:

item инициализируется в списке инициализации членов конструктора QueueItem( const Type &t )

: item(t) { next = 0; }

определения конструктора QueueItem: };

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

16.2.1. Аргументы шаблона для параметров-констант

Параметр шаблона класса может и не быть типом. На аргументы, подставляемые вместо таких параметров, накладываются некоторые ограничения. В следующем примере мы изменяем определение класса Screen (см. главу 13) на шаблон, параметризованный высотой и шириной:

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

QueueItem( const Type & ); Следующее определение приемлемо, если у типа, для которого конкретизируется



template <int hi, int wid> class Screen { public:

Screen() : height( hi ), width( wid ), cursor ( 0 ), screen( hi * wid, # )

{ }

...

private:

string screen;

string::size type cursor; short height;

short width;

typedef Screen<24,80> termScreen; termScreen hp2621;

Screen<8,24> ancientScreen;

Выражение, с которым связан параметр, не являющийся типом, должно быть константным, т. е. вычисляемым во время компиляции. В примере выше typedef termScreen ссылается на экземпляр шаблона Screen<24,80>, где аргумент шаблона для hi равен 24, а для wid - 80. В обоих случаях аргумент - это константное выражение.

Однако для шаблона BufPtr конкретизация приводит к ошибке, так как значение указателя, получающееся при вызове оператора new() , становится известно только во

template <int *ptr> class BufPtr { ... };

ошибка: аргумент шаблона нельзя вгчисть во время компиляции

время выполнения:

BufPtr< new int[24] > bp;

Не является константным выражением и значение неконстантного объекта. Его нельзя использовать в качестве аргумента для параметра-константы шаблона. Однако адрес любого объекта в области видимости пространства имен, в отличие от адреса локального объекта, является константным выражением (даже если спецификатор const отсутствует), поэтому его можно применять в качестве аргумента для параметра-

template <int size> Buf { ... }; template <int *ptr> class BufPtr { ... };

int size val = 1024; const int c size val = 1024;

Buf< 1024 > buf0; правильно Buf< c size val > buf1; правильно

Buf< sizeof(size val) > buf2; правильно: sizeof(int) BufPtr< &size val > bp0; правильно

ошибка: нельзя вычислить во время компиляции

константы. Константным выражением будет и значение оператора sizeof:

Buf< size val > buf3;



template < class Type, int size > class FixedArray {

public:

FixedArray( Type *ar ) : count( size ) {

for ( int ix = 0; ix < size; ++ix ) array[ ix ] = ar[ ix ];

private:

Type array[ size ]; int count;

int ia[4] = { 0, 1, 2, 3 };

аргумента для задания значения этого параметра:

FixedArray< int, sizeof( is ) / sizeof( int ) > ia );

Выражения с одинаковыми значениями считаются эквивалентными аргументами для параметров-констант шаблона. Так, все три экземпляра Screen ссылаются на один и тот

const int width = 24; const int height = 80;

все это Screen< 24, 80 > Screen< 2*12, 40*2 > scr0; Screen< 6+6+6+6, 20*2 + 40 > scr1;

же конкретизированный из шаблона класс Screen<24,80>: Screen< width, height > scr2;

Между типом аргумента шаблона и типом параметра-константы допустимы некоторые преобразования. Их множество является подмножеством преобразований, допустимых для аргументов функции:

трансформации l-значений, включающие преобразование 1-значения в г-

template <int *ptr> class BufPtr { ... }; int array[10];

значение, массива в указатель и функции в указатель:

BufPtr< array > bpObj; преобразование массива в указатель

template <const int *ptr> class Ptr { ... }; int iObj;

преобразования квалификаторов:

Вот еще один пример, иллюстрирующий использование параметра-константы для представления константного значения в определении шаблона, а также применение его



1 ... 260 261 262 [ 263 ] 264 265 266 ... 395

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика