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: // оператор вывода объектов типа Animal
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)\n";
37: }
38:
39: Animal::Animal():
40: itsWeight(0)
41: {
42: // cout << "Animal()\n";
43: }
44:
45: Animal::~Animal()
46: {
47: // cout << "Destroyed an animal...\n";
48: }
49:
50: template // объявление шаблона и параметра
51: class Array // параметризованный класс
52: {
53: public:
54: Array(int itsSlze = DefaultSize);
55: Array(const Array &rhs);
56: ~Array() { delete [] pType; }
57:
56: Array& operator=(const Array&);
59: T& operator[](int offSet) { return pType[offSet]; }
60: const T& operator[](int offSet) const
61: { return pType[offSet]; }
62: int GetSize() const { return itsSize; }
63:
64: // функция-друг
65: friend ostream& operator<< (ostream&, const Array&);
66:
67: private:
68: T *рТуре;
69: int itsSize;
70: };
71:
70: template
72: ostream& operator<< (ostream& output, const Array& theArray)
73: {
74: for (int i = 0; i
75: output << "[" << i << "] " << theArray[i] << endl;
76: return output;
77: }
78:
79: // Ряд выполнений...
80:
81: // выполнение конструктора
82: template
83: Array::Array(int size):
84: itsSize(size)
85: {
86: рТуре = new T[size];
67: for (int i = 0; i
88: pType[i] = 0;
89: }
90:
91: // конструктор-копировщик
92: template
93: Array::Array(const Array &rhs)
94: {
95: itsSize = rhs.GetSize();
96: рТуре = new T[itsSize];
97: for (int i = 0; i
98: pType[i] = rhs[i];
99: }
100:
101: void IntFillFunction(Array& theArray);
102: void AnimalFillFunction(Array& theArray);
103:
104: int main()
105: {
106: Array intArray;
107: Array animalArray;
108: IntFillFunction(intArray);
109: AnimalFillFunction(animalArray);
110: cout << "intArray...\n" << intArray;
111: cout << "\nanimalArray...\n" << aninalArray << endl;
112: return 0;
113: }
114:
115: void IntFillFunction(Array& theArray)
116: {
117: bool Stop = false;
118: int offset, value;
119: while (!Stop)
120: {
121: cout << "Enter an offset (0-9) ";
122: cout << "and a value, (-1 to stop): " ;
123: cin >> offset >> value;
124: if (offset < 0)
125: break;
126: if (offset > 9)
127: {
128: cout << "***Please use values between 0 and 9.***\n";
129: continue;
130: }
131: theArray[offset] = value;
132: }
133: }
134:
135:
136: void AnimalFillFunction(Array& theArray)
137: {
138: Animal * pAnimal;
139: for (int i = 0; i
140: {
141: pAnimal = new Animal;
142: pAnimal->SetWeight(i*100);
143: theArray[i] = *pAnimal;
144: delete pAnimal; // копия была помещена в массив
145: }
146: }
Результат:
Enter an offset (0- 9) and а value. ( -1 to stop) 1 10
Enter an offset (0- 9) and а value. ( -1 to stop) 2 20
Enter an offset (0- 9) and а value. ( -1 to stop) 3 30
Enter an offset (0- 9) and а value. ( -1 to stop) 4 40
Enter an offset (0- 9) and а value. ( -1 to stop) 5 50
Enter an offset (0- 9) and а value. ( -1 to stop) 6 60
Enter an offset (0- 9) and а value. ( -1 to stop) 7 70
Enter an offset (0- 9) and а value. ( -1 to stop) 8 80
Enter an offset (0- 9) and а value. ( -1 to stop) 9 90
Enter an offset (0-9) and а value. ( -1 to stop) 10 10
***Please use values between 0 and 9.***
Enter an offset (0-9) and a value. (-1 to stop): -1 -1
intArray:... [0] 0 [1] 10 [2] 20
[3] 30
[4] 40
[5] 50
[6] 60
[7] 70
[8] 80
[9] 90
animalArray:...
[0] 0
[1] 100
[2] 200
[3] 300
[4] 400
[5] 500
[6] 600
[7] 700
[8] 800
[9] 900
Анализ:В целях экономии места большая часть выполнения класса Array не показана в этом листинге. Класс Animal объявляется в строках 6—23. И хотя структура этого класса предельно упрощена, тем не менее в нем содержится собственный оператор вывода (<<), позволяющий выводить на экран объекты массива типа Animal.
Обратите внимание, что в классе Animal объявлен конструктор по умолчанию (конструктор без параметров, который еще называют стандартный). Без этого объявления нельзя обойтись, поскольку при добавлении объекта в массив используется конструктор по умолчанию данного объекта. При этом возникают определенные трудности, о которых речь пойдет ниже.
В строке 101 объявляется функция IntFillFunction(), параметром которой является целочисленный массив. Обратите внимание, что эта функция не принадлежит шаблону, поэтому может принять только массив целочисленных значений. Аналогичным
образом в строке 102 объявляется функция AnimalFillFunction(), которая принимает массив объектов типа Animal.
Эти функции выполняются по-разному, поскольку заполнение массива целых чисел отличается от заполнения массива объектов Animal.
Специализированные функции
Если разблокировать выражения вывода на экран в конструкторах и деструкторе класса Animal (см. листинг 19.5), то обнаружится, что конструктор и деструктор объектов Animal вызываются значительно чаще, чем ожидалось.
При добавлении объекта в массив вызывается стандартный конструктор объекта. Однако конструктор класса Array также используется для присвоения нулевых значений каждому члену массива, как показано в строках 59 и 60 листинга 19.2.
В выражении someAnimal = (Animal) 0; вызывается стандартный оператор operator= для класса Animal. Это приводит к созданию временного объекта Animal с помощью конструктора, который принимает целое число (нуль). Этот временный объект выступает правым операндом в операции присваивания, после чего удаляется деструктором.
Читать дальше