Освой самостоятельно С++ за 21 день.
Шрифт:
Рис. 10.3 Пример глубинного копирования
Когда выполнение программы выходит за область видимости класса CAT, автоматически запускается деструктор. Выполнение деструктора класса CAT показано в строках с 37 по 43. Оператор delete применяется к обоим указателям — itsAge и itsWeigth, после чего оба указателя для надежности
Перегрузка операторов
Язык C++ располагает рядом встроенных типов данных, включая int, real, char и т.д. Для работы с данными этих типов используются встроенные операторы — суммирования (+) и умножения (<<). Кроме того, в C++ сушествует возможность добавлять и перегружать эти операторы для собственных классов.
Чтобы в деталях рассмотреть процедуру перегрузки операторов, в листинге 10.6 создается новый класс Counter. Объект класса Counter будет использоваться в других приложениях для подсчета циклов инкрементации, декрементации и других повторяющихся процессов.
Листинг 10.6. Класс Counter
1: // Листинг 10.6.
2: // Класс Counter
3:
4: int
5: #include <iostream.h>
6:
7: class Counter
8: {
9: public:
10: Counter;
11: ~Counter{ }
12: int GetItsValconst { return itsVal; }
13: void SetItsVal(int x) { itsVal = x; }
14:
15: private:
16: int itsVal;
17:
18: };
19:
20: Counter::Counter:
21: itsVal(0)
22: { }
23:
24: int main
25: {
25: Counter i;
27: cout << "The value of i is " << i.GetItsVal << endl;
28: return 0;
29: }
Результат:
The value of i is 0
Анализ: Судя по определению в строках программы с 7 по 18, это совершенно бесполезный класс. В нем объявлена единственная переменная-член типа int. Конструктор по умолчанию, который объявляется в строке 10 и выполняется в строке 20, инициализирует переменную-член нулевым значением.
В отличие от обычной переменной типа int, объект класса Counter не может использоваться в операциях приращения, прибавляться, присваиваться или подвергаться другим манипуляциям. В связи с этим выведение значения данного объекта на печать также сопряжено с рядом трудностей.
Запись Функции инкремента
Ограничения использования объекта нового класса, которые упоминались выше, можно преодолеть путем перегрузки операторов. Например, существует несколько способов восстановления возможности приращения объекта класса Counter. Один из них состоит в том, чтобы перегрузить функцию инкрементации, как показано в листинге 10.7.
Листинг 10.7. Добавление в класс оператора инкремента
1: // Листинг 10.7.
2: // Добавление в класс Counter оператора инкремента
3:
4: int
5: #include <iostream.h>
6:
7: class Counter
8: {
9: public:
10: Counter;
11: ~Counter{ }
12: int GetItsValconst { return itsVal; }
13: void SetItsVal(int x) { itsVal = x; }
14: void Increment { ++itsVal; }
15:
16: private:
17: int itsVal;
18:
19: };
20:
21: Counter::Counter:
22: itsVal(0)
23: { }
24:
25: int main
26: {
27: Counter i;
28: cout << "The value of i is " << i.GetItsVal << endl;
29: i.Increment;
30: cout << "The value of i is " << i.GetItsVal << endl;
31: return 0;
32: }
Результат:
The value of i is 0
The vglue of i is 1
Анализ: В листинге 10.7 добавляется функция оператора инкремента, определенная в строке 14. Хотя программа работает, выглядит она довольно неуклюже. Программа из последних сил старается перегрузить ++operator, но это можно реализовать другим способом.
Перегрузка префиксных операторов
Чтобы перегрузить префиксный оператор, можно использовать функцию следующего типа:
returnType Operator op (параметры)
В данном случае ор — это перегружаемый оператор. Тогда для перегрузки оператора преинкремента используем функцию
void operator++
Этот способ показан в листинге 10.8.
Листинг 10.8 Перегрузка оператора преинкремента
1: // Листинг 10.8.
2: // Перегрузка оператора преинкремента в классе Counter
3:
4: int
5: #include <iostream.h>
6:
7: class Counter
8: {
9: public:
10: Counter;
11: ~Counter{ }
12: int GetItsValconst { return itsVal; }
13: void SetItsVal(int x) { itsVal = x; }
14: void Increment { ++itsVal; >
15: void operator++ < ++itsVal; }
16:
17: private:
18: int itsVal;
19:
20: };
21:
22: Counter::Counter:
23: itsVal(0)
24: { }
25:
26: int main
27: {
28: Counter i;
29: cout << "The value of i is " << i.GetItsVal << endl;
30: i.Increment;
31: i cout << "The value of i is " << i.GetItsVal << endl;
32: ++i;
33: cout << "The value of i is " << i.GetItsVal << endl;
34: return 0;
35: }
Результат:
The value of i is 0