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

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


тип1 возвращаемого значения и обоих параметров конкретизирован! из шаблона класса Queue extern Queue< complex<double> >

foo( Queue< complex<double> > &, Queue< complex<double> > & );

указатель на функцию-член класса, конкретизированного из шаблона Queue bool (Queue<double>::*pmf)() = 0;

/ / явное приведение 0 к указате на экземпляр Queue

допустимо употребление типа обычного класса:

Queue<char*> *pqc = static cast< Queue<char*>* > ( 0 );

Объекты типа класса, конкретизированного по шаблону Queue, объявляются и

extern Queue<double> eqd; Queue<int> *pqi = new Queue<int>; Queue<int> aqi[1024];

int main() { int ix;

if ( ! pqi->is empty() ) ix = pqi->remove();

...

for ( ix = 0; ix < 1024; ++ix )

eqd[ ix ].add( ix ); ...

используются так же, как объекты обычных классов:

В объявлении и определении шаблона можно ссылаться как на сам шаблон, так и на

объявление шаблона функции

template <class Type> void bar( Queue<Type> &,

ссылается на обобщенный шаблон Queue<double> & ссылается на конкретизированный шаблон

конкретизированный по нему класс:

Однако вне такого определения употребляются только конкретизированные экземпляры. Например, в теле обычной функции всегда надо задавать фактические аргументы

void foo( Queue<int> &qi ) {

Queue<int> *pq = &qi;

...

шаблона Queue:

Queue qs; ошибка: как конкретизируется шаблон? Конкретизированный шаблон класса Queue можно использовать в программе всюду, где



class Matrix;

Matrix *pm; правильно: определение класса Matrix знать необязательно

класс его знать необязательно:

void inverse( Matrix & ); тоже правильно

Поэтому объявление указателей и ссылок на конкретизированный шаблон класса не приводит к его конкретизации. (Отметим, что в некоторых компиляторах, написанных до принятия стандарта C++, шаблон конкретизируется при первом упоминании имени конкретизированного класса в тексте программы.) Так, в функции foo() объявляются

Queue<int> не конкретизируется при таком использовании в foo() void foo( Queue<int> &qi ) {

Queue<int> *pqi = &qi;

...

указатель и ссылка на Queue<int>, но это не вызывает конкретизации шаблона Queue:

Определение класса необходимо знать, когда определяется объект этого типа. В следующем примере определение obj1 ошибочно: чтобы выделить для него память,

class Matrix;

Matrix obj1; ошибка: класс Matrix не определен class Matrix { ... };

class

компилятору необходимо знать размер класса Matrix:

Matrix obj2; правильно

Таким образом, конкретизация происходит тогда, когда определяется объект класса, конкретизированного по этому шаблону. В следующем примере определение объекта qi приводит к конкретизации шаблона Queue<int>:

Queue<int> qi; конкретизируется Queue<int>

Определение Queue<int> становится известно компилятору именно в этой точке, которая называется точкой конкретизации данного класса.

Если имеется указатель или ссылка на конкретизированный шаблон, то конкретизация также производится в момент обращения к объекту, на который они ссылаются. В определенной выше функции foo() класс Queue<int> конкретизируется в следующих случаях: когда разыменовывается указатель pqi, когда ссылка qi используется для

Шаблон класса конкретизируется только тогда, когда имя полученного экземпляра употребляется в контексте, где требуется определение шаблона. Не всегда определение класса должно быть известно. Например, перед объявлением указателей и ссылок на



void foo( Queue<int> &qi ) {

Queue<int> *pqi = &qi;

Queue<int> конкретизируется в результате вызова функции-члена pqi->add( 255 );

...

членам или функциям-членам этого класса:

Определение Queue<int> становится известным компилятору еще до вызова функции-члена add() из foo() .

Напомним, что в определении шаблона класса Queue есть также ссылка на шаблон

template <class Type> class Queue { public:

...

private:

QueueItem<Type> *front; QueueItem<Type> *back;

QueueItem: };

При конкретизации Queue типом int члены front и back становятся указателями на QueueItem<int>. Следовательно, конкретизированный экземпляр Queue<int> ссылается на экземпляр QueueItem, конкретизированный типом int. Но поскольку соответствующие члены являются указателями, то QueueItem<int> конкретизируется лишь в момент их разыменования в функциях-членах класса Queue<int>.

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

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

template <class Type> class QueueItem { public:

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

вида?

получения значения именуемого объекта и когда pqi или qi употребляются для доступа к



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

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