Шаблонные классы предоставляют большие возможности, чем шаблонные функции. В таком классе определяются все его данные и функции, а фактические типы обрабатываемых данных задаются в качестве параметров позже, при создании объектов этого класса.
При создании шаблонных классов нужно обратить внимание на следующие возможности:
Ø Шаблон типа необходимо задавать также при определении функции после имени класса, для которого эта функция определяется. Шаблон типа задается в угловых скобках;
Ø При определении функции, ему должно в каждом случае предшествовать задание шаблонов типа со служебным словом template;
Ø При создании объектов шаблонного класса после имени класса в угловых скобках задается конкретизация типа шаблона, то есть имя встроенного типа или типа пользователя, например:
Array <int> iar, *piar;
Array <double> dar, *pdar;
Ø Дружественные функции также можно задавать в шаблонном классе по общим требованиям к дружественным функциям.
Ø Для некоторых объектов шаблонный класс может не подойти. В таких случаях следует задавать реализацию различных функций для конкретного типа. Но лучше все-таки создавать шаблонные классы для объектовродственных типов, например, числовых, строковых, очередей, стеков и т. п.
Используя классы, можно определить новые типы данных. Например, в языке С++ отсутствует такой тип, как множество, но его легко реализовать с помощью шаблонного класса.
Рассмотрим понятие множество. Множество – это какой-то «черный ящик», в который можно поместить элемент данного множества, проверить его наличие в множестве, исключить какой-либо элемент из множества. Будем считать, что все элементы множества должны быть уникальны (т.е. могут входить во множество только 1 раз). Порядок следования элементов во множестве не имеет значения, однако мы будем создавать множества элементов, упорядоченных по возрастанию.
Множество является подмножеством другого множества, если в этом другом множестве можно найти все элементы, имеющиеся в первом подмножестве. Например, множество {A, B} является подмножеством множества {A, B, C}.
Для множеств определены следующие операции:
Ø объединение множеств – это элементы, принадлежащие обоим множествам. Если A = {‘2’, ’4’, ’A’, ’B’, ’F’}, а B = {‘1’, ’4’, ’C’, ’B’, ’E’},то A + B = {‘2’, ’4’, ’A’, ’B’, ’F’, ‘1’, ‘C’, ‘E’};
Ø пересечение множеств – это те элементы, которые принадлежат одновременно обоим множествам A*B = {’4’, ’B’};
Ø разность множеств – это исключение из левого множества элементов, которые имеются в правом A – B = {‘2’, ’A’, ’F’};
Ø симметричная разность множеств – это набор элементов, которые входят только в одно из множеств (т.е. это объединение минус пересечение множеств): {‘2’, ’A’, ’F’, ‘1’, ‘C’, ‘E’}
Ø для множеств могут быть определены операции сравнения ==, !=, >=, <=, а также операция определения принадлежности элемента данному множеству.
Пример : Класс, описывающий множество.
В этом примере множество строится на основе линейного массива, память под который выделяется динамически.
#include <iostream>
#include <stdlib.h>
using namespace std;
#define DEFSET 100 // Размер множества по умолчанию
template <class Stype> class Set
// Stype – условное название типа элементов
{
Stype *SetPtr; // Указатель на члены множества
int MemSize; // Размер памяти, выделенный множеству
int NumMembers; // Количество элементов множества
// операторы ввода – вывода:
template<typename Stype> friend istream& operator>> (istream& stream, Set &ob);
template<typename Stype> friend ostream& operator << (ostream& stream, Set &ob);
// закрытые функции:
void insert(Stype member); // добавление элемента
void remove(Stype member); // удаление элемента
int find (Stype member); // возвращение индекса элемента
/* эта функция позволяет использовать операторы типа: s = 2 + s; функция не может быть членом класса, поскольку левый операнд – не объект этого класса */
Set<Stype> operator + (Set &ob); //Создание объединения