Шаблоны классов
Шаблон классов (class template) в руководствах программиста иногда называется generic class или class generator. Шаблон действительно помогает компилятору сгенерировать определение конкретного класса по образу и подобию заданной схемы. Разработчики компилятора C++ различают два термина: class template и template class. Первый означает абстрактный шаблон классов, а второй – одно из его конкретных воплощений. Пользователь может сам создать template class для какого-то типа данных. В этом случае созданный класс отменяет (overrides) автоматическую генерацию класса по шаблону для этого типа данных.
Рассмотрим стандартный пример, иллюстрирующий использование шаблона для автоматического создания классов, которые реализуют функционирование абстрактного типа данных "Вектор линейного пространства". Элементами вектора могут быть объекты различной природы. В примере создаются векторы целых, вещественных, объектов некоторого класса circle (вектор окружностей) и указателей на функции. Для вектора из элементов любого типа тела методов шаблона одинаковы, поэтому и есть смысл объединить их в шаблоне:
#include <iostream> #include <string> #include <math.h> //====== Шаблон классов "Вектор линейного пространства" template <class T> class Vector { //====== Данные класса private: Т *data; // Указатель начала массива компонентов int size; // Размер массива //====== Методы класса public: Vector(int); ~Vector() { delete [] data; } int Size() { return size; } T& operator [] (int i) { return data[i]; } }; //====== Внешняя реализация тела конструктора template <class T> Vector<T>::Vector(int n) { data = new Т[n]; size = n; }; //====== Вспомогательный класс"Круг" class Circle { private: //====== Данные класса int х, у; // Координаты центра int r; // Радиус public: //====== Два конструктора Circle () { х = у = r = 0; } Circle (int a, int b, int с) { x = a; У = b; r = с; } //====== Метод для вычисления площади круга double area () { return 3.14159*r*r; } }; //====== Глобальное определение нового типа //====== указателя на функцию typedef double (*Tfunc) (double); //====== Тестирование void main () { //===== Генерируется вектор целых Vector <int> x(5); for (int i=0; i < x.SizeO; ++i) { x[i] = i; // Инициализация cout << x[i] << ' '; // Вывод } cout << ' \n '; //===== Генерируется вектор вещественных Vector <float> y(10); for (i=0; i < y.SizeO; ++i) { y[i] = float (i); // Инициализация cout << y[i] << ' '; // Вывод } cout " ' \n'; //==== Генерируется вектор объектов класса Circle Vector <Circle> z(4); for (i=0; i< z.SizeO; ++i) // Инициализация z[i] = Circle(i+100,i + 100,i+20); cout << z[i].area() << " "; // Вывод } cout << ' \n'; //==== Генерируется вектор указателей на функции Vector <Tfunc> f(3); cout <<"\nVector of function pointers: "; f[0] = sqrt; // Инициализация f[l] = sin; f[2] = tan; for (i=0; i< f.Size(); ++i) cout << f[i](3.) << ' '; // Вывод cout << "\n\n"; }