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

1 ... 265 266 267 [ 268 ] 269 270 271 ... 395


#include <iostream> #include Queue.h

int main() {

Queue<int> qi;

конкретизиртся оба экземпляра

ostream& operator<<(ostream &os, const Queue<int> &) ostream& operator<<(ostream &os, const QueueItem<int> &) cout << qi << endl;

int ival;

for ( ival = 0; ival < 10; ++ival )

qi.add( ival );

cout << qi << endl; int err cnt = 0;

for ( ival = 0; ival < 10; ++ival ) { int qval = qi.remove(); if ( ival != qval ) err cnt++;

cout << qi << endl; if ( !err cnt )

cout << !! queue executed ok\n ; else cout << ?? eue errors: << err cnt << endl; return 0;

После компиляции и запуска программа выдает результат:

0 1 2 3 4 5 6 7 8 9 > !! queue executed ok

Упражнение 16.6

Пользуясь шаблоном класса Screen, определенным в упражнении 16.5, реализуйте операторы ввода и вывода (см. упражнение 15.6 из раздела 15.2) в виде шаблонов. Объясните, почему вы выбрали тот, а не иной способ объявления друзей класса Screen, добавленных в его шаблон.

16.5. Статические члены шаблонов класса

В шаблоне класса могут быть объявлены статические данные-члены. Каждый конкретизированный экземпляр имеет собственный набор таких членов. Рассмотрим операторы new() и delete() для шаблона QueueItem. В класс QueueItem нужно

static QueueItem<Type> *free list;

добавить два статических члена:

static const unsigned QueueItem chunk;

Модифицированное определение шаблона QueueItem выглядит так:



#include <cstddef>

template <class Type> class QueueItem {

...

private:

void *operator new( size t ); void operator delete( void *, size t );

...

static QueueItem *free list; static const unsigned QueueItem chunk;

...

Операторы new() и delete() объявлены закрытыми, чтобы предотвратить создание объектов типа QueueItem вызывающей программой: это разрешается только членам и друзьям QueueItem (к примеру, шаблону Queue).

template <class Type> void*

QueueItem<Type>::operator new( size t size )

QueueItem<Type> *p; if ( ! free list ) {

size t chunk = QueueItem chunk * size; free list = p =

reinterpret cast< QueueItem<Type>* > ( new char[chunk] );

for ( ; p != &free list[ QueueItem chunk - 1 ]; ++p )

p->next = p + 1; p->next = 0;

p = free list;

free list = free list->next; return p;

Оператор new() можно реализовать таким образом:

template <class Type> void QueueItem<Type>::

operator delete( void *p, size t )

static cast< QueueItem<Type>* >( p )->next = free list; free list = static cast< QueueItem<Type>* > ( p );

А реализация оператора delete() в1глядит так:

Теперь остается инициализировать статические члены free list и QueueItem chunk. Вот шаблон для определения статических данных-членов:



/* для каждой конкретизации QueueItem сгенерировать

* соответствщий free list и инициазировать его нулем

template <class T>

eueItem<T> *eueItem<T>::free list = 0;

/* для каждой конкретизации QueueItem сгенерировать

* соответствщий QueueItem chunk и инициализировать его значением 24

template <class T> const unsigned int

QueueItem<T>::QueueItem chunk = 24;

Определение шаблона статического члена должно быть вынесено за пределы определения самого шаблона класса, которое начинается с ключевого слово template с последующим списком параметров <class T>. Имени статического члена предшествует префикс QueueItem<T>:: , показывающий, что этот член принадлежит именно шаблону QueueItem. Определения таких членов помещаются в заголовочный файл Queue.h и должны включаться во все файлы, где производится их конкретизация. (В разделе 16.8 мы объясним, почему решили делать именно так, и затронем другие вопросы, касающиеся модели компиляции шаблонов.)

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

ошибка: QueueItem - это не реальн конкретизированн экземпляр int ival0 = QueueItem::QueueItem chunk;

int ival1 = QueueItem<string>::QueueItem chunk; правильно класса:

int ival2 = QueueItem<int>::QueueItem chunk; правильно

Упражнение 16.7

Реализуйте определенные в разделе 15.8 операторы new() и delete() и относящиеся к ним статические член: screenChunk и freeStore для шаблона класса Screen, построенного в упражнении 16.6.

16.6. Вложенные типы шаблонов классов

Шаблон класса QueueItem применяется только как вспомогательное средство для реализации Queue. Чтобы запретить любое другое использование, в шаблоне QueueItem имеется закрытый конструктор, позволяющий создавать объекты этого класса исключительно функциям-членам класса Queue, объявленным друзьями QueueItem. Хотя шаблон QueueItem виден во всей программе, создать объекты этого класса или обратиться к его членам можно только при посредстве функций-членов Queue.



1 ... 265 266 267 [ 268 ] 269 270 271 ... 395

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