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

1 ... 256 257 258 [ 259 ] 260 261 262 ... 395


class Queue {

public:

Queue(); ~Queue() ;

Type& remove();

void add( const Type & );

bool is empty() ; bool is full(); private: ...

Определение Queue могло бы выглядеть так:

Вопрос в том, какой тип использовать вместо Type? Предположим, что мы решили реализовать класс Queue, заменив Type на int. Тогда Queue может управлять коллекциями объектов типа int. Если бы понадобилось поместить в очередь объект другого типа, то его пришлось бы преобразовать в тип int, если же это невозможно,

Queue qObj; string str(

string str( vivisection );

qObj.add( 3.14159 ); правильно: в очередь помещен объект 3

компилятор выдаст сообщение об ошибке:

qObj.add( str ); ошибка: нет преобразования из string в int

Поскольку любой объект в коллекции имеет тип int, то яз1к C++ гарантирует, что в очередь можно поместить либо значение типа int, либо значение, преобразуемое в такой тип. Это подходит, если предстоит работа с очередями объектов только типа int. Если же класс Queue должен поддерживать также коллекции объектов типа double, char, комплексные числа или строки, подобная реализация оказывается слишком ограничительной.

Конечно, эту проблему можно решить, создав копию класса Queue для работы с типом double, затем для работы с комплексными числами, затем со строками и т.д. А поскольку имена классов перегружать нельзя, каждой реализации придется дать уникальное имя: IntQueue, DoubleQueue, ComiplexQueue, StringQueue. При необходимости работать с другим классом придется снова копировать, модифицировать и переименовывать.

Такой метод дублирования кода крайне неудобен. Создание различных уникальных имен для Queue представляет лексическую сложность. Имеются и трудности администрирования: любое изменение общего алгоритма придется вносить в каждую реализацию класса. В общем случае процесс ручной генерации копий для индивидуальных типов никогда не кончается и очень сложен с точки зрения сопровождения.

bool is empty();

определить, заполнена ли очередь:

bool is full() ;



template <class Type> class Queue { public:

Queue();

~Queue() ;

Type& remove();

void add( const Type & );

ViPP1 П о rTr,.rt \ .

bool is empty() ; bool is full();

private: ...

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

Queue<int> qi;

Queue< complex<double> > qc;

строки, программисту достаточно написать:

Queue<string> qs;

Реализация Queue представлена в следующих разделах с целью иллюстрации определения и применения шаблонов классов. В реализации используются две абстракции шаблона:

сам шаблон класса Queue предоставляет описанный выше открытый интерфейс и пару членов: front и back. Очередь реализуется с помощью связанного списка;

шаблон класса QueueItem представляет один узел связанного списка Queue. Каждый помещаемый в очередь элемент сохраняется в объекте QueueItem, который содержит два члена: value и next. Тип value будет различным в каждом экземпляре класса Queue, а next - это всегда указатель на следующий объект QueueItem в очереди.

Прежде чем приступать к детальному изучению реализации этих шаблонов, рассмотрим,

template <class T>

как они объявляются и определяются. Вот объявление шаблона класса QueueItem:

class QueueItem;

Как объявление, так и определение шаблона всегда начинаются с ключевого слова template. За ним следует заключенный в угловые скобки список параметров шаблона, разделенных занятыми. Список не бывает нуст1м. В нем могут быть параметры-типы, представляющие некоторый тин, и параметры-константы, представляющие некоторое константное выражение.

К счастью, механизм шаблонов C++ позволяет автоматически генерировать такие типы. Шаблон класса можно использовать при создании Queue для очереди объектов любого



template <class T1, class T2, class T3>

У шаблона класса может быть несколько параметров-типов:

class Container;

Однако ключевое слово class или typename должно предшествовать каждому.

ошибка: должно быть <typename T, class U> <typename T, typename U>

template <typename T, U>

Следующее объявление ошибочно:

class collection;

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

Не являющийся типом параметр шаблона представляет собой обычное объявление. Он показывает, что следующее за ним имя - это потенциальное значение, употребляемое в определении шаблона в качестве констант:. Так, шаблон класса Buffer может иметь параметр-тип, представляющий типы элементов, хранящихся в буфере, и параметр-

template <class Type, int size>

константу, содержащий его размер:

class Buffer;

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

Параметр-тип шаблона состоит из ключевого слова class или typename (в списке параметров они эквивалентны), за которым следует идентификатор. (Ключевое слово typename не поддерживается компиляторами, написанными до принятия стандарта C++. В разделе 10.1 подробно объяснялось, зачем это слово было добавлено в язык.) Оба ключевых слова обозначают, что последующее имя параметра относится к встроенному или определенному пользователем типу. Например, в приведенном выше определении шаблона QueueItem имеется один параметр-тип T. Допустим1м фактическим аргументом для T является любой встроенный или определенный пользователем тип, такой, как int, double, char*, complex или string.



1 ... 256 257 258 [ 259 ] 260 261 262 ... 395

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