Программирование >>  Программирование на языке c++ 

1 ... 80 81 82 [ 83 ] 84 85 86 ... 159


выражения (см. класс А), а также типы и константные выражения (см. класс В). При описании шаблона можно сразу же задать значения константных выражений (см. класс В).

#include <iostream.h> template<int i, char c> struct A {

void example(void) { cout << i \t с endl; }

template<class T.int i = 789> class В {

Tt; public:

B(Tx):t(x){};

void example(void) { cout i \t t endl;}

void main(void)

{ const 1=1234; объявление целой константы

const char C=#; объявление символьной константы A<I,C> a; в шаблоне можно использовать только

константные выражения a.exampleO; Результат; 1234 # B<double,(11*3+55)/2> Ь(345.678); b.exampleO; Результат: 44 345.678

B<char*> bb( Portugal ); второй элемент был задан выше bb.exampleO; Результат; 789 Portugal

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

template<class T,int i = 789, int j = 222, char с = W> class Al {...};

template<class T,int i = 789, int j, char с = W> class A2 {...}; template<class T,int i = 789, int j, char c> class A3 {...}; template<class T,int i, int j = 222, char с > class A4 {...};

Второй пример показывает, какие объекты могут считаться и какие объекты не могут считаться объектами одного типа.



#include <iostream.h> template<class T.int i> class В {

Tt; public:

B(T x) : t(x) {}; конструктор

void example(void) { cout i \t t endl;}

void main{void)

{ B<double,(11*3-l-55)/2> b1(345.678),b2(1.1);

b1=b2; это разрешенное присваивание (bl и Ь2 -

объекты одного типа) bI.exampleO; Результат: 44 1.1

B<double,22> Ь3(6); ЬЗ - объект нового типа ЬЗ=Ь2; ошибка: cannot convert

B<double,44> to B<double,22> B<float,(11*3+55)/2> b4(8.8); b4 - объект нового типа Ь2=Ь4; ошибка: cannot convert

B<float,44> to B<double,44>

В программе только объекты bl и Ь2 являются объектами одного типа. Объекты ЬЗ и Ь4 имеют другие типы. Таким образом, в программе есть три типа объектов: Ь1,Ь2; ЬЗ; Ь4.

б.б. Совместное использование шаблонов

и принципов наследования

Между шаблонами и наследованием сушествует внутренняя взаимосвязь. Действительно, шаблоны позволяют отразить обшность различных типов. С другой стороны, принципы наследования позволяют выразить общность интерфейса для различных классов. Интерфейс, как известно, определяет правила взаимодействия класса с внешней средой. Рассмотрим пример:

class name : public string {...................};

array<name*,10> name array1;



array<string*,10> string array; array<name*,10> name array2;

Здесь объекты name arrayl и пате аггау2 имеют одинаковые типы, а тип объекта string array будет уже другим. Тот факт, что класс name является производным классом базового класса string, уже не принимается во внимание. В этом случае рассмотренные ранее соглашения о соответствующем использовании указателей на объекты базового и производного классов не могут быть применены. Здесь существует аналогия с невозможностью использования стандартных преобразований типов (см. § 6.5). В результате следующее выражение будет ошибочным:

string array = name array; ошибка

Рассмотрим теперь пример совместного использования шаблонов и принципов наследования. Пусть задан следующий шаблон:

template<class general type, class implementation details> class my class

: public container class<general type>, private implementation details

{ ............................. };

Похожий шаблон был рассмотрен в § 6.3 (см. также рис. 6.2). Здесь использованы принципы наследования, позволяющие построить некоторый производный класс my class из двух базовых классов: container class и implementation details. Первый базовый класс содержит все необходимые функции для организации интерфейса (взаимодействия) класса my class с внешней средой. Второй базовый класс содержит все необходимые функции, которые не надо использовать за пределами класса (они не интересуют внешнюю среду). В результате эти функции не должны являться частью внешнего интерфейса. Они необходимы только для выполнения чего-то полезного внутри класса my class (например, они могут динамически выделять память в соответствии с поставляемыми типами элементов, хранимых в некотором контейнере - container class). Тогда эти функции можно скрыть, т. е. запретить их использование за пределами класса my class. Это достигается назначением атрибута private базовому классу implementation details. Тем самым мы предотвращаем возможные измене-



1 ... 80 81 82 [ 83 ] 84 85 86 ... 159

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