Час зберігання об'єкту
Для того, щоб мати можливість оперувати даними у програмі, ми оголошуємо змінні та створюємо об'єкти. Дані, які містять змінні та об'єкти, знаходяться у пам'яті. Для спрощення та відповідності зі стандартом мови, називатимемо і змінні простих вбудованих типів і екземпляри класів просто об'єктами (object).
Коли ми створюємо об'єкт у програмі - ми вказуємо, що необхідно виділити пам'ять для збереження даних, які містить цей об'єкт. У деякий момент, ця пам'ять буде вивільнена (наприклад, якщо програма завершила виконання). Час протягом якого, ці данні будуть доступні, поки пам'ять яка їх містить не буде вивільнена для інших потреб, ми називатимемо часом життя об'єкту (object lifetime).
Час життя пов'язаний з тривалістю зберігання (storage duration) об'єкту. Ми познайомимося з двома видами часу зберігання: автоматичний та статичний.
Автоматичний час зберігання
Звичайні локальні об'єкти, які ми оголошуємо всередині деякого блоку коду, існують лише в межах цього блоку. Тому, коли виконання програми вийде за межі блоку коду, пам'ять автоматично вивільниться.
Покажемо це на прикладі. Для наочної демонстарції, створимо простий клас:
Цей клас має два спеціальні методи: конструктор MyClass()
та деструктор ~MyClass()
. Нагалаємо, що для будь якого класу конструктор завжди автоматично викликається, коли створюється новий об'єкт класу. А деструктор, завжди автоматично викликається коли об'єкт класу знищується.
Тепер напишемо дуже просту програму:
Тут об'єкт obj
створено всередині окремого блоку коду. Після запуску програми ми побачимо вивід у консоль:
Тобто, як тільки виконання блоку коду завершилось - одразу ж викликався деструктор об'єкту і його було видалено з пам'яті.
Автоматичний час зберігання мають також об'єкти оголошені всередині функцій, блоків if
, циклів, тощо. Тому ніколи не можна використовувати посилання чи вказівник на автоматичний об'єкт поза межами блоку, в якому він існує. Наприклад, якщо ми маємо функцію яка повертає посилання чи вказівник на локальну змінну всередині функції (чого не можна робити!) і ми скористаємося цим вказівником\посиланням, то у кращому випадку програма аварійно завершиться, а у гіршому - буде працювати некоректно (і як часто буває в таких випадках - дуже дивно).
Ткож варто пам'ятати, що у випадку примітивних типів такіх як int
, float
, bool
, вказівників тощо, автоматичні змінні завжди необхідно ініціалізовувати початковим значенням. Вони не ініціазізуються за замовчуванням автоматично, і якщо їх не ініціалізувати - вони міститимуть довільне значення (по суті, сміття з пам'яті).
Статичний час зберігання
Глобальні об'єкти, а також об'єкти, які оголошені зі специфікатором static
існують до завершення роботи програми.
Розглянемо приклад:
Консольний вивід виглядатиме так:
Як ми бачимо з прикладу, об'єкт оголошений глобально був створений ше до початку виконання main()
, а видалений вже після закінчення роботи програми.
У випадку статично змінної (наприклад оголошеної всередині функції):
Вивід виглядатиме так:
На прикладі цієї програми ми бачимо, що статичний об'єкт було створено при першому виклику функції func()
, а знищено вже після роботи програми. Зверніть увагу: навіть при другому виклику функції func()
повторного створення об'єкту не відбулося.
Статичні об'єкти (оголошені як static
) створюються лише один раз за час роботи програми і існують до кінця її роботи. Наприклад, якщо ми оголосимо змінну типу int
у функції та присвоїмо їй якесь значення, то при наступному виклику ця змінна матиме те ж саме значення, яке ми їй присвоїли.
Last updated