Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Билеты по ООП.doc
Скачиваний:
4
Добавлен:
14.04.2019
Размер:
596.48 Кб
Скачать

41. Классы-шаблоны

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

Общая форма объявления класса – шаблона приведена ниже:

template <class T> class имя_класса {

};

Здесь T является параметром – типом, который будет указан при создании объекта класса. При необходимости можно определить несколько типов – шаблонов, используя список и запятую в качестве разделителя.

После создания класса – шаблона можно создать конкретный экземпляр класса и объекты этого класса, использую общую форму:

имя_класса <тип> объект;

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

Функции – члены класса – шаблона являются сами по себе автоматически шаблонами.

В следующей программе создаётся класс – шаблон stack, реализующий стандартный стек «последним вошёл – первым вышел». Он может использоваться для реализации стека с произвольным типом данных.

Листинг 4

// демонстрация класса-шаблона stack

#include <iostream>

using namespace std;

const int SIZE = 100;

// создание класса-шаблона stack

template <class SType> class stack{

SType stck[SIZE];

int tos;

public:

stack();

~stack();

void push(SType i);

SType pop();

};

// функция-конструктор stack

template <class SType> stack<SType>::stack()

{

tos = 0;

cout << "Stack initialized\n";

}

// функция-деструктор stack

template <class SType> stack<SType>::~stack()

{

cout << "Stack destroyed\n";

}

// помещение объекта в стек

template <class SType> void stack<SType>::push(SType i)

{

if(tos==SIZE) {

cout << "Stack is full.\n";

return;

}

stck[tos] = i;

tos++;

}

// извлечение объекта из стека

template <class SType> SType stack<SType>::pop()

{

if(tos==0) {

cout << "Stack underflow.\n";

return 0;

}

tos--;

return stck[tos];

}

int main()

{

stack<int> a;

stack<char> c;

a.push(1);

a.push(2);

cout << a.pop() << " ";

cout << a.pop() << "\n";

register int i;

for(i=0; i<10; i++) c.push((char) 'A'+i);

for(i=0; i<10; i++) cout << c.pop();

cout << "\n";

return 0;

}

Класс-шаблон может иметь несколько типов-шаблонов. Достаточно объявить все типы-шаблоны в виде списка, разделённого запятыми.

// используются два типа-параметра

#include <iostream>

using namespace std;

template <class Type1, class Type2> class Myclass

{

Type1 i;

Type2 j;

public:

Myclass(Type1 a, Type2 b){ i=a; j=b; }

void show(){cout << i << " " << j << "\n";}

};

int main()

{

Myclass<int, double> ob1(10, 0.23);

Myclass<char, char *> ob2('X', "This is a test");

ob1.show();

ob2.show();

return 0;

}

42. Использование пространства имён

Поскольку пространства с глобальной областью видимости добавляются к системе, то имеется возможность коллизии имён. Это становится особенно актуальным при использовании библиотек, разработанных различными независимыми производителями. Использование namespace позволяет разбить глобальное пространство имён для того, чтобы решить проблему.

Общая форма namespace следующая:

namespace имя{

// объявление объекта

}

Пример

namespace MyNameSpace {

int i, k;

void myfunc(int j) {cout << j;}

}

Здесь i, k и myfunc() составляют область видимости пространства имён MyNameSpace.

Поскольку пространство имён определяет область видимости, то для ссылки на объекты, определённые в пространстве имён, необходимо использовать оператор области видимости. Например:

MyNameSpace::i =10;

Если элементы области видимости будут использоваться часто, то можно использовать директиву using для упрощения доступа к ним. Инструкция using имеет две общие формы записи:

using namespace имя;

using имя::член;

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

using MyNameSpace::k; // видим только k

k = 10; // допустимо, поскольку k видим

using namespace MyNameSpace; // все члены MyNameSpace видимы

i = 10;