При работе с большими объектами эти вызовы конструктора и деструктора могут оказать слишком ощутимое влияние на скорость работы программы и использование памяти компьютера. Для иллюстрации этой идеи в листинге 9.10 создается пользовательский объект SimpleCat. Реальный объект имел бы размеры побольше и обошелся бы дороже, но и этого примера вполне достаточно, чтобы показать, насколько часто вызываются конструктор-копировщик и деструктор.
Итак, в листинге 9.10 создается объект SimpleCat, после чего вызываются две функции. Первая функция принимает объект Cat как значение, а затем возвращает его как значение. Вторая же функция принимает указатель на объект, а не сам объект, и возвращает указатель на объект.
Листинг 9.10. Передача объектов как ссылок с помощью указателей
1: // Листинг 9.10.
2: // Передача указателей на объекты
3:
4: #include
5:
6: class SimpleCat
7: {
8: public:
9: SimpleCat ; // конструктор
10: SimpleCat(SimpleCat&); // конструктор-копировщик
11: ~SimpleCat; // деструктор
12: };
13:
14: SimpleCat::SimpleCat
15: {
16: cout << "Simple Cat Constructor...\n";
17: }
18:
19: SimpleCat::SimpleCat(SimpleCat&)
20: {
21: cout << "Simple Cat Copy Constructor...\n";
22: }
23:
24: SimpleCat::~SimpleCat
25: {
26: cout << "Simple Cat Destructor...\n";
27: }
28:
29: SimpleCat Function0ne (SimpleCat theCat);
30: SimpleCat* FunctionTwo (SimpleCat *theCat);
31:
32: int main
33: {
34: cout << "Making a cat,.,\n";
35: SimpleCat Frisky;
36: cout << "Calling FunctionOne,,,\n";
37: FunctionOne(Frisky);
38: cout << "Calling FunctionTwo..,\n";
39: FunctionTwo(&Frisky);
40: return 0;
41: }
42:
43: // Функция FunctionOne, передача как значения
44: SimpleCat FunctionOne(SimpleCat theCat)
45: {
46: cout << "Function One. Roturning,,,\ri";
47: return theCat;
48: }
49:
50: // Функция FunctionTwo, передача как ссылки
51: SimpleCat* FunctionTwo (SimpleCat *theCat)
52: {
53: cout << "Function Two. Returning...\n";
54: return theCat;
55: }
Результат:
Making a cat...
Simple Cat Constructor...
Calling FunctionOne...
Simple Cat Copy Constructor...
Function One. Returning...
Simple Cat Copy Constructor...
Simple Cat Destructor...
Simple Cat Destructor...
Calling FunctionTwo...
Function Two. Returning...
Simple Cat Destructor...
Примечание:
Анализ:
В строках 6-12 объявляется весьма упрошенный класс SimpleCat. Конструктор, конструктор-копировщик и деструктор — все компоненты класса выводят на экран свои информативные сообщения, чтобы было точно известно, когда они вызываются.В строке 34 функция main выводит свое первое сообщение, которое является первым и в результатах работы программы. В строке 35 создается экземпляр объекта класса SimpleCat. Это приводит к вызову конструктора, что подтверждает сообщение, выводимое этим конструктором (строка 2 в результатах работы программы).
В строке 36 функция main "докладывает" о вызове функции FunctionOne, которая выводит свое сообщение (строка 3 в результатах работы программы). Поскольку функция FunctionOne вызывается с передачей объекта класса SimpleCat по значению, в стек помещается копия объекта SimpleCat как локального для вызываемой функции. Это приводит к вызову конструктора копии, который "вносит свою лепту" в результаты работы программы (сообщение в строке 4).
Выполнение программы переходит к строке 46, которая принадлежит телу вызванной функции, выводящей свое информативное сообщение (строка 5 в результатах работы программы). Затем эта функция возвращает управление программой вызывающей функции, и объект класса SimpleCat вновь возвращается как значение. При этом создается еще одна копия объекта за счет вызова конструктора-копировщика и, как следствие, на экран выводится очередное сообщение (строка 6 в результатах работы программы).
Значение, возвращаемое из функции FunctionOne, не присваивается ни одному объекту, поэтому ресурсы, затраченные на создание временного объекта при реализации механизма возврата, просто выброшены на ветер, как и ресурсы, затраченные на его удаление с помощью деструктора, который заявил о себе в строке 7 в результатах работы программы. Поскольку функция FunctionOne завершена, локальная копия объекта выходит за область видимости и разрушается, вызывая деструктор и генерируя тем самым сообщение, показанное в строке 8 в результатах работы программы.
Управление программой возвращается к функции main, после чего вызывается функция FunctionTwo, но на этот раз параметр передается как ссылка. При этом никакой копии объекта не создается, поэтому отсутствует и сообщение от конструктора- копировщика. В функции FunctionTwo выводится сообщение, занимающее строку 10 в результатах работы программы, а затем выполняется возвращение объекта класса SimpleCat (снова как ссылки), поэтому нет никаких обращений к конструктору и деструктору.