Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
+ООП_Навч_посібник.doc
Скачиваний:
7
Добавлен:
01.07.2025
Размер:
6.58 Mб
Скачать

13.5.1. Конструктори, деструктори і передача об'єктів

Хоча передача функціям нескладних об'єктів як аргументів – достатньо проста процедура, проте при цьому можуть відбуватися непередбачені події, що мають відношення до конструкторів і деструкторів. Щоб розібратися у цьому, розглянемо таку програму.

Код програми 13.8. Демонстрація механізму використання конструкторів, деструкторів і передачі об'єктів

#include <vcl>

#include <iostream> // Для потокового введення-виведення

#include <conio> // Для консольного режиму роботи

using namespace std; // Використання стандартного простору імен

class myClass { // Оголошення класового типу

int num;

public:

myClass(int izm) { num = izm; cout << "Створення\n";}

~myClass() { cout << "Руйнування\n";}

int getVal() { return num;}

};

void display(myClass a_ob)

{

cout << "num= " << a_ob.getVal() << "\n";

}

int main()

{

myClass A_ob(10); // Створення об'єкта класу

display(A_ob);

getch(); return 0;

}

У процесі виконання ця програма виводить такі несподівані результати:

Створення

num= 10

Руйнування

Руйнування

Як бачимо, тут виконується одне звернення до функції конструктора (під час створення об'єкта A_ob), але чомусь відбувається два звернення до функції деструктора. Давайте з'ясуємо, у чому тут справа.

Під час передачі об'єкта функції створюється його копія (і ця копія стає параметром у функції). Створення копії означає появу нового об'єкта. Коли виконання функції завершується, копія аргументу (тобто параметр) руйнується. Тут виникає відразу два запитання. По-перше, чи викликається конструктор об'єкта під час створення копії? По-друге, чи викликається деструктор об'єкта під час руйнування копії? Відповіді на ці запитання можуть здивувати Вас.

Оскільки під час виклику функції створюється копія аргументу, то звичайний конструктор не викликається. Натомість викликається конструктор копії об'єкта, який визначає, як має створюватися копія об'єкта1. Але, якщо в класі безпосередньо не визначено конструктор копії, то мова програмування C++ надає його за замовчуванням. Конструктор копії за замовчуванням створює побітову (тобто однакову) копію об'єкта. Оскільки звичайний конструктор використовують для ініціалізації тільки деяких даних об'єкта, то він не повинен викликатися для створення копії вже наявного об'єкта. Такий виклик змінив би його вміст. Під час передачі об'єкта функції потрібно використовувати поточний стан об'єкта, а не його початковий стан.

Однак, коли функція завершує свою роботу, то руйнується копія об'єкта, який використовується як аргумент, для чого викликається деструктор цього об'єкта. Необхідність виклику деструктора пов'язана з виходом об'єкта з області видимості його функцією, у якій він використовується. Саме тому попередня програма мала два звернення до деструктора. Перше відбулося при виході з області видимості параметра функції display(), а друге – під час руйнування об'єкта A_ob у функції main() після завершення роботи програми.

Отже, коли об'єкт передається функції як аргумент, звичайний конструктор не викликається. Замість нього викликається конструктор копії, який за замовчуванням створює побітову (тобто, однакову) копію цього об'єкта. Але коли ця копія руйнується (зазвичай при виході за межі області видимості його після завершення роботи функції), то обов'язково викликається деструктор.