СОЗДАНИЕ ШАБЛОНА КЛАССА
Предположим, к примеру, вы создаете класс массива, в котором есть методы для вычисления суммы и среднего значения хранимых в массиве чисел. Предположим, что вы работаете с массивом типа int, и ваш класс мог бы выглядеть так:
class array
{
public:
array(int size);
long sum(void);
int average_value(void);
void show_array(void);
int add_value(int);
private:
int *data;
int size;
int index;
};
Следующая программа I_ARRAY.CPP использует класс array ддя работы со значениями типа int.
#include iostream.h
#include stdlib.h
class array
{
public:
array(int size);
long sum(void);
int average_value(void);
void show_array(void);
int add_value(int) ;
private:
int *data;
int size;
int index;
};
array::array(int size)
{
data = new int [size];
if (data == NULL)
{
cerr "Недостаточно памяти - программа завершается " endl;
exit(l);
}
array:: size = size;
array::index = 0;
}
long array::sum(void)
{
long sum = 0;
for (int i = 0; i index; i++) sum += data[i];
return(sum);
}
int array::average_value(void)
{
long sum = 0;
for (int i = 0; i index; i++) sum += data[i];
return (sum / index);
}
void array::show_array(void)
{
for (int i = 0; i index; i++) cout data[i] ' ';
cout endl;
}
int array::add_value(int value)
{
if (index == size) return(-1); // массив полон
else
{
data[index] = value;
index++;
return(0); // успешно
}
}
void main(void)
{
array numbers (100); // массив из 100 эл-тов
int i;
for (i = 0; i 50; i++) numbers.add_value(i);
numbers.show_array();
cout "Сумма чисел равна " numbers.sum () endl;
cout "Среднее значение равно " numbers.average_value() endl;
}
Как видите, программа распределяет 100 элементов массива, а затем заносит в массив 50 значений с помощью метода add_value. В классе array переменная index отслеживает количество элементов, хранимых в данный момент в массиве. Если пользователь пытается добавить больше элементов, чем может вместить массив, функция add_value возвращает ошибку. Как видите, функция average_value использует переменную index для определения среднего значения массива. Программа запрашивает память для массива, используя оператор new, который подробно рассматривается в уроке 31.
Шаблоны классов
По мере того как количество создаваемых вами классов растет, вы обнаруживаете, что некоторый класс, созданный для одной программы (или, возможно, для этой), очень похож на требующийся вам сейчас. Во многих случаях классы могут отличаться только типами. Другими словами, один класс работает с целочисленными значениями, в то время как требующийся вам сейчас должен работать со значениями типа. float. Чтобы увеличить вероятность повторного использования существующего кода, C++ позволяет вашим программам определять шаблоны классов. Если сформулировать кратко, то шаблон класса определяет типонезависимый класс, который в дальнейшем служит для создания объектов требуемых типов. Если компилятор C++ встречает объявление объекта, основанное на шаблоне класса, то для построения класса требуемого типа он будет использовать типы, указанные при объявлении. Позволяя быстро создавать классы, отличающиеся только типом, шаблоны классов сокращают объем программирования, что, в свою очередь, экономит ваше время.
Пойдем дальше. Теперь предположим, что вашей программе необходимо работать с массивом значений с плавающей точкой, кроме того, что она работает с целочисленным массивом. Один из способов обеспечить поддержку массивов различных типов состоит в создании разных классов. С другой стороны, используя шаблоны классов, вы можете избавиться от необходимости дублировать классы. Ниже представлен шаблон класса, который создает общий класс array:
templateclass T, class T1 class array
{
public:
array(int size);
T1 sum (void);
T average_value(void);
void show_array(void);
int add_value(T);
private:
T *data;
int size;
int index;
};
Этот шаблон определяет символы типов T и T1. В случае массива целочисленных значений Т будет соответствовать int, а T1 — long. Аналогичным образом для массива значений с плавающей точкой значения Т и Т1 равны float. Теперь потратьте время, чтобы убедиться, что вы поняли, как компилятор С++ будет подставлять указанные вами типы вместо символов Т и Т1.
Далее, перед каждой функцией класса вы должны указать такую же запись со словом template. Кроме того, сразу же после имени класса вы должны указать типы класса, например array T, T1::average_value. Следующий оператор иллюстрирует определение функции average_value для этого класса:
templateclass Т, class T1 Т arrayT, T1::average_value(void)
{
T1 sum = 0;
int i;
for (i = 0; i index; i++) sum += data[i] ;
return (sum / index);
}
После создания шаблона вы можете создавать класс требуемого типа, указывая имя класса, а за ним в угловых скобках необходимые типы, как показано ниже:
Имя шаблона //---- array int, long numbers (100); ------//Типы шаблона
array float, float values(200);
Программа GENARRAY. CPP использует шаблон класса array для создания двух классов, один из которых работает со значениями типа int, а второй — со значениями типа float.
#include iostream.h
#include stdlib.h
templateclass T, class T1 class array
{
public:
array(int size);
T1 sum(void);
T average_value(void);
void show_array(void);
int add_value(T);
private:
T *data;
int size;
int index;
};
templateclass T, class T1 arrayT, t1::array(int size)
{
data = new T[size];
if (data == NULL)
{
cerr "Недостаточно памяти - программа завершается" endl;
exit(l);
}
array::size = size;
array::index = 0;
}
templateclass T, class T1 Tl arrayT, Tl::sum(void)
{
T1 sum = 0;
for (int i = 0; i index; i++) sum += data[i];
return(sum);
}
templateclass T, class T1 T arrayT, T1::average_value(void)
{
Tl sum =0;
for (int i = 0; i index; i++) sum += data[i];
return (sum / index);
}
templateclass T, class T1 void arrayT, T1::show_array(void)
{
for (int i = 0; i index; i++) cout data[i] ' ';
cout endl;
}
templateclass T, class T1 int arrayT, T1::add_value(T value)
{
if (index == size)
return(-1); // Массив полон
else
{
data[index] = value;
index++;
return(0); // Успешно
}
}
void main(void)
{
// Массив из 100 элементов
arrayint, long numbers(100)7
// Массив из 200 элементов
arrayfloat, float values(200);
int i;
for (i = 0; i 50; i++) numbers.add_value(i);
numbers.show_array();
cout "Сумма чисел равна " numbers.sum () endl;
cout "Среднее значение равно " numbers.average_value() endl;
for (i = 0; i 100; i++) values.add_value(i * 100);
values.show_array();
cout "Сумма чисел равна." values.sum() endl;
cout "Среднее значение равно " values.average_value() endl;
}
Лучшим способом понять шаблоны классов будет напечатать две копии этой программы. В первой копии замените все символы T и Т1 на int и long. A во второй замените Т и Т1 на float.
Объявление объектов, основанных на шаблоне класса
Для создания объектов с использованием шаблона класса вы просто должны указать имя шаблона класса, за которым между левой и правой угловыми скобками укажите типы, которыми компилятор заменит символы Т, T1, T2 и т. д. Затем ваша программа должна указать имя объекта (переменной) со значениями параметров, которые вы хотите передать конструктору класса, как показано ниже:
template_class_nametypel, type2 object_name( parameter1, parameter2);
Когда компилятор C++ встречает такое объявление, он создает класс, основанный на указанных типах. Например, следующий оператор использует шаблон класса array для создания массива типа char, в котором хранится 100 элементов:
arraychar, int small_numbers(100) ;