|
Программирование >> Инициализация объектов класса, структура
#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.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |