Все конструкторы и деструкторы класса Animal (строки 33—48) выводят на экран сообщения, сигнализирующие об их вызове.
В строках 74-81 объявляется конструктор класса Array. В строках 114-118 показан специализированный конструктор Array для массива объектов типа Animal. Обратите внимание, что в этом специализированном конструкторе не делается никаких явных присвоений и исходные значения для каждого объекта Animal устанавливаются стандартным конструктором.
При первом выполнении этой программы на экран выводится ряд сообщений. В строке 1 результатов выполнения программы зафиксированы сообщения трех стандартных конструкторов, вызванных при создании массива. Затем пользователь вводит четыре числа, которые помещаются в массив целых чисел.
После этого управление передается функции AnimalFillFunction(). Здесь в области динамического обмена создается временный объект Animal (строка 161), а его значение используется для модификации объекта Animal в массиве (строка 162). В следующей же строке (с номером 163) временный объект Animal удаляется. Этот процесс повторяется для каждого члена массива и отражен в строке 6 результатов выполнения программы.
В конце программы созданные массивы удаляются, а при вызове их деструкторов также удаляются и все их объекты. Процесс удаления отражен в строке 16 результатов выполнения программы.
При следующем выполнении программы (результаты показаны в строках 18-43) были закомментированы несколько строк программного кода (со 114 по 118), содержащие специализированный конструктор класса Array. В результате при выполнении программы для создания массива объектов Animal вызывается конструктор шаблона, показанныйвстроках74-81.
Это приводит к созданию временных объектов Animal для каждого члена массива (строки программы 79 и 80), что отражается в строках 18-20 результатов выполнения программы.
Во всех остальных аспектах, результаты выполнения двух вариантов программы, как и следовало ожидать, идентичны.
Статические члены и шаблоны
В шаблоне можно объявлять статические переменные-члены. В результате каждый экземпляр шаблона будет иметь собственный набор статических данных. Например, если добавить статическую переменную-член в шаблон Array (например, для подсчета количества созданных массивов), то в рассмотренной выше программе будут созданы две статические переменные-члена: одна для подсчета массивов объектов типа Animal и другая для массивов целых чисел. Добавление статической переменной-члена и статической функции в шаблон Array показано в листинге 19.7.
Листинг 19.7. Использование статических переменных-членов и функций-членов с шаблонам
1: #include
2:
3: const int DefaultSize = 3;
4:
5: // Обычный класс, из объектов которого создается массив
6: class Animal
7: {
8: public:
9: // конструкторы
10: Animal(int);
11: Animal();
12: ~Animal();
13:
14: // методы доступа
15: int GetWeight() const { return itsWeight: }
16: void SetWeight(int theWeight) { itsWeight = theWeight }
17:
18: // дружественные операторы
19: friend ostream& operator<< (ostream&, const Animal&);
20:
21: private:
22: int itsWeight;
23: };
24:
25: // оператор вывода обьектов типа Anlmal
26: ostream& operator<<
27: (ostream& theStream, const Animal& theAnimal)
28: {
29: theStream << theAnimal.GetWeight();
30: return theStream;
31: }
32:
33: Animal::Animal(int weight):
34: itsWeight(weight)
35: {
36: //cout << "animal(int) ";
37: }
38:
39: Animal::Animal():
40: itsWeight(0)
41: {
42: // cout << "animal() ";
43: }
44:
45: Animal::~Animal()
46: {
47: // cout << "Destroyed an animal...";
48: }
49:
50: template // объявляем шаблон и параметр
51: class Array // параметризованный класс
52: {
53: public:
54: // конструкторы
55: Array(int itsSize = DefaultSize);
56: Array(const Array &rhs);
57: ~Array() { delete [] рТуре; itsNumberArrays-; }
58:
59: // операторы
60: Array& operator=(const Array&);
61: T& operator[](int offSet) { return pType[offSet]; }
62: const T& operator[](int offSet) const
63: { return pType[offSet]; }
64: // аксессоры
65: int GetSize() const { return itsSize; }
66: static int GetNumberArrays() { return itsNumberArrays; }
67:
68: // функция-друг
69: friend ostream& operator<< (ostream&, const Array&); 70:
71: private:
72: T *pType;
73: int itsSize;
74: static int itsNumberArrays;
75: };
76:
77: template
78: int Array::itsNumberArrays = 0;
79:
80: template
81: Array::Array(int size = DefaultSize):
82: itsSize(size)
83: {
84: pType = new T[size];
85: for (int i = 0; i
86: pType[i] = (T)0;
87: itsNumberArrays++;
88: }
89:
90: template
91: Array& Array::operator=(const Array &rhs)
92: {
93: if (this == &rhs)
94: return *this;
95: delete [] pType;
96: itsSize = rhs.GetSize();
97: pType = new T[itsSize];
98: for (int i = 0; i
99: pType[i] = rhs[i];
100: }
101:
102: template
103: Array::Array(const Array &rhs)
104: {
105: itsSize = rhs.GetSize();
106: pType = new T[itsSize];
107: for (int i = 0; i
108: pType[i] = rhs[i];
109: itsNumberArrays++;
110: }
111:
112:
Читать дальше