Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

chast2

.pdf
Скачиваний:
9
Добавлен:
10.06.2015
Размер:
431.28 Кб
Скачать

tamplate<список параметров шаблонов>//(1)<>-обязательно Спецификация шаблонного класса //(2)

Параметрышаблона класса как и шаблона функциимогут быть либо типизирующими либо нетипизирующими.

Создание конкретного класса по шаблону (т.е. специализации класса) обеспечивается конкретизацией типизирующих параметров.

Далее рассмотрим только типизирующие параметры.

Процесс создания специализации класса принято называть инстанциированием шаблона. В С++ допускаются 3 режима инстанциирования шаблона классов:

1. Неявная специализация шаблонов класса.

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

2. Явная (полная) специализация шаблонов классов.

Когда явно задается полная конкретная реализациякласса, включая определения методов данной специализации.

Данный режим применяется если в какой-то конкретной специализации необходимо применить алгоритмы отличные от тех что заданы в шаблоне.

3. Частичная спецификация шаблонов.

Далее рассмотрим только первый режим.

Как и при определении обычных классов, методы шаблона могут определяться:

-внутри спецификации шаблона и тогда они при соответствующей организации компилятора будут встроенными.

-вне спецификациишаблона, при этом внутри спецификациишаблона делается только прототип метода.

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

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

template<typename A> //(3) определяемшаблон с одним типизирующим параметром class ourPair{ //(4)

A x,y;//(5) приватные поля public: //(6)

// далее определяем шаблоны методов для семейства классов, обратить внимание на формат употребления имени шаблона класса.

ourPair(A x1=A(0),A y1=A(1)):x(x1),y(y1){} //(7) конструктор умолчания; его действия сводятся к инициализации полей создаваемого объекта

A getDiv(void) // встроенный метод {return A(x/y);}//(9)

//далее определяем встроенную функцию-операцию перегружающую операцию сложения.

ourPair2<A> operator +(ourPair<A>&p)//(10)

{return ourPair2<A>(x+p.x,y+p.y);}//(11) все кроме слова return, это вызов конструктора void display() //(12) встроенный метод класса

{cout<<" x="<<x<<" y="<<y<<endl;}//(13) };//(14) конец определения шаблона класса

Комментарии.

1.В определении шаблона особую роль играет его имя (ourPair).Необходимо четко понимать,что это не имя какого-то конкретного класса,т.е. специализации шаблона, а параметризуемое в последующих использованиях имя семейства классов. Соответственно роль имени конкретного класса, т.е специализации, играет синтаксическая конструкция вида ourPair<A>. В конкретных специализациях, общий символ А заменяется на конкретный тип данных. Обратить внимание что имя конструктора совпадает с именем шаблона без параметризации (7).

2.Дополнительно к явно определенным методам компилятор в процессе специализации шаблона автоматически создает деструктор, конструктор копирования и функцию-операцию присваивания с такими прототипами:

~ourPair();//(15)

ourPair(const ourPair<A>&)//(16)

ourPair <A>&operator=(const ourPair<A>&);//(17)

Здесь надо обратить внимание на то,что в качествеимени конструктора и деструктора используется непараметризованное имя шаблона.

К данному моменту мы определили только шаблон семейства классов. В процессе же компиляции программы, должны создаваться конкретные класса, т.е. специализации. В связи с этим приведенныйвыше текст спецификации работает только до стадии препроцессорной обработки исходного кода (часть 1 п 1.2),в ходе же препроцессорной обработки компилятор, используя шаблон как схему, создает полный текст модуля в котором будут даны определения конкретных классов. Именно этот полный текст и будет подвергаться компиляции.

Продолжим пример

В теле функции mane приведем операторы инстанциированияшаблона (т.е. создание конкретных классов) с одновременным созданием объектов этих конкретных классов. (Мы рассматриваем только первый режим инкапсуляции).

ourPair<int> Obj1,Obj2(12,5);//(18) будет создана специализация шаблон, а именно конкретный класс с именем ourPair<int> в котором данныебудут иметьтип int. Кроме того с помощью соответствующей специализации конструктора умолчания при А=int будут созданы 2 объекта этого класса,причем первый создается со значениями полей х и у по умолчанию, а второй с явно заданными значениями полей.

cout<<"Obj1:\t"; Obj1.display();//(19) выводим в консольное окно значения полей первого объекта. cout<<"Obj2.getDiv()="<<Obj2.getDiv()<<endl;//(20)

Obj1=Obj1+Obj2;//(21) cout<<"Obj1:\t"; Obj1.display();//(22)

ourPair<double>Obj3(10,3);//(23) создаем другую специализацию шаблона в которой данные будут относится к типу double

На рис 7.1 дана наглядная иллюстрация данного примера и общего тезиса опоследовательности формирования текстов программы.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]