- •Введение. Принципы объектно-ориентированного программирования
- •Глава 1. Классы и объекты
- •1.1. Операция разрешения области видимости ::
- •1.2. Перечислимый тип
- •1.3. Модификатор const
- •1.4. Новый тип данных – ссылка &
- •Inline определение_функции
- •2. Определение класса. Сокрытие информации.
- •3. Объект.
- •4. Конструкторы и деструкторы
- •4.1.Назначение конструктора
- •4.2. Конструктор копирования
- •X::X(X&); // где X – имя класса
- •4.3. Деструктор
- •5. Неявный указатель this
- •6. Перегрузка операций
- •7. Примеры перегрузки некоторых операций
- •7.1. Перегрузка операции [ ]
- •7.2. Перегрузка операции ()
- •7.6. Перегрузка операции (тип)
- •8. Дружественность
- •Istream
- •10. Массивы объектов.
- •11. Функции- и классы-шаблоны
- •11.1 Функции-шаблоны (родовые функции)
- •11.2 Классы-шаблоны
- •12. Член-данные класса – объекты другого класса: агрегированные классы.
- •Глава 2. Наследование. Полиморфизм
- •1. Базовый и порожденный классы
- •2. Конструкторы порожденного класса
- •3. Стандартные преобразования при наследовании
- •4. Множественное наследование. Виртуальный базовый класс
- •4.1. Прямые базовые классы
- •4.2. Виртуальный базовый класс
- •5. Полиморфизм, раннее и позднее связывание, виртуальные функции
- •5.1 Раннее (статическое) и позднее (динамическое) связывание
- •5.2. Определение виртуальной функции
- •5.3. Чистая виртуальная функция и абстрактный класс
- •5.4. Правила определения виртуальных функций
- •5.5. Механизм позднего связывания
- •6. Библиотека fstream – работа с файлами
- •Глава 3. Библиотека стандартных шаблонов (бсш). Контейнеры
- •1. Контейнер. Структура бсш.
- •2. Контейнер Vector – динамический массив
- •Контейнер list – список
- •4. Контейнер Set – множество
- •Содержание
- •Глава 1. Классы и объекты
- •Глава 2. Наследование. Полиморфизм
- •Глава 3. Библиотека стандартных шаблонов (бсш). Контейнеры
11.2 Классы-шаблоны
Так же, как и функции-шаблоны, могут быть определены и классы-шаблоны.
Определение. Класс-шаблон – это класс, в котором одни и те же член-данные могут быть разных типов, а действия над ними – одинаковые. Формат определения класса-шаблона
template <class X,class Y,...> class имя_класса
{ X определение член-данных;
Y определение член-данных;
.......
};
Здесь X и Y – условное обозначение типов данных.
Использование такого класса в функциях следующее:
имя_класса <конкретные_типы> имя_объекта[(арг-ты констр-а)];
При компиляции для каждого списка типов данных, указанного в < >, будет создан свой экземпляр класса.
Рассмотрим пример класса-шаблона Stack. В стек кладутся целые и комплексные числа, строки.
enum boolean {FALSE, TRUE};
#include "string.hpp"
#include "Complex.hpp"
template <class T> class Stack
{ T *a; int max, n;
public:
Stack(int k = 50)
{a = new T [max = k]; n = 0; }
~Stack( ) {delete [ ]a;} // деструктор
Stack(Stack<T> &); // конструктор копирования
Stack <T> operator = (Stack <T> );
void Push(T b) // положить в стек элемент b
{if (Full( ))
{cout << "Стек переполнен!"; return;}
a[n++] = b;
}
T Pop( ) // удалить элемент из стека
{if (!isEmpty( )) return a[--n];}
T Top() // взять значение с вершины стека
{return a[n - 1];}
boolean isEmpty( ) // стек пуст?
{if (n = = 0) return TRUE;
return FALSE;
}
boolean Full( ); // стек заполнен?
friend ostream & operator << (ostream &, Stack <T> &); // потоковый вывод
};
template <class T> Stack< T>:: Stack(Stack<T> & b)
{int i;
max = b.max; n = b.n;
a= new T[max];
for(i = 0; i < n; i++) a[i] = b.a[i];
}
template <class T> boolean Stack<T>:: Full()
{ if (n = = max) return TRUE; // да, заполнен
return FALSE; // нет, не заполнен
}
template <class T> ostream & operator << (ostream & r, Stack <T> & b)
{ int i;
if (b.isEmpty( )) {r << "\nстек пуст"; return r;}
for(i = 0; i < b.n; i++) cout << ' ' << b.a[i];
return r;
}
template <class T> Stack<T> Stack<T>:: operator = (Stack<T> b)
{if (& b != this)
{delete []a;
a = new T[max = b.max]; n = b.n;
for(int i = 0; i < n; i++) a[i] = b.a[i];
return *this;
} }
void main()
{Stack <Complex> c(5); // cоздается экземпляр стека комплексных чисел
Stack <String> s(5); // cоздается экземпляр стека строк
Stack <int> a(2), c; // стек целых чисел
Stack <float> b(3); // стек вещественных чисел
String b4("bbbb"); // строка “bbbb”
int i;
c.Push(Complex(2, 3)); // компл. число 2 + 3 * i => в стек комплексных чисел
c.Push(3.5); // комп. число 3.5 + 3.5 * i => в стек комплексных чисел
s. Push(«dddddd»); // строка “dddddd” => в стек строк
s.Push(b4); // строка “bbbb” => в стек строк
a.Push(77); // число 77 => в стек целых чисел
a.Push(9); // число 9 => в стек целых чисел
a.Push(-10); // Сообщение «Стек переполнен!”
cout << "\n Стек комплексных чисел ";
cout << c; // работают 2 перегруженные операции потокового вывода << для классов Stack и Complex
cout<<"\n Стек строк: ";
while (!s.isEmpty()) // пока стек не пуст
cout << s.Pop(); // работает перегруженная в классе String операция <<
//Стек строк опустел
c = a; // перегруж. операция = переписывает стек целых чисел a в c
cout << "\n Стек целых чисел" << c;
cout << ”\n В вершине стека число “ << a.Top();
cout << "\nСтек вещественных чисел b = " << b;
}
Замечание. Так как действия над данными в классах-шаблонах одинаковые, а типы данных могут быть произвольные, то такие классы еще называют контейнерными. В настоящее время существует большой набор стандартных классов-шаблонов: стеки, очереди, деревья, строки, упорядоченные массивы и др.
