Основи програмування на С ++ для початківців

Конструктор копіювання в С ++

Коли новачки вивчають програмування, першим ділом, при розгляді нової теми, виникає питання – для чого необхідна та чи інша “вещь” про яку зараз належить дізнатися. Відповімо відразу на це питання: “Навіщо потрібен конструктор копіювання?”.

Конструктор копіювання необхідний для того, щоб ми могли створювати “реальні” (а не побитовые) копії для об'єктів класу. Така копія об'єкта може знадобитися в наступних випадках:

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

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

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

Використання конструктора копіювання – прекрасний спосіб обійти ці помилки і проблеми. він створить “реальну” копію об'єкта, яка матиме особисту область динамічної пам'яті.

Конструктор копіювання синтаксично виглядає так:

Нижче розберемо нескладний, але дуже показовий приклад. У ньому будуть розглянуті всі 3 випадку в яких бажано застосовувати конструктор копіювання. Буде створено клас, містить конструктор без параметрів, конструктор копіювання і деструктор.

Щоб приклад був не надто громіздким, конструктори і деструктор будуть виводити на екран повідомлення типу “спрацював конструктор”, “спрацював дектруктор”…  Виділяти і звільняти пам'ять не будемо.

Нам відмінно буде видно скільки разів спрацюють конструктори а скільки разів деструктор. очевидно, що деструкція (якби він звільняв пам'ять) не повинен спрацьовувати більшу кількість разів, ніж конструктор, виділяє пам'ять.

Приклад:

Конструктор без параметрів буде викликатися під час створення нових об'єктів класса. Конструктор копіювання  – під час створення копій об'єкта. Деструктор срабатывает при удалении и реального объекта и его копии. В теле функций все описано подробно и не требует дополнительных комментариев.

Запустивши програму побачимо в консолі наступне:

конструктор копіювання в с ++,  конструктор копії c ++,  програмування на с ++ з нуля

Подивимося що програма видала в консоль. блок 1 –  під час створення нового об'єкта, спрацював конструктор без параметрів. В блоці 2  ми розмістили функціюshowFunc(). Під час передачі в неї “об'єкта-параметра” по значению, спрацював конструктор копіювання і створилася “реальна” копія об'єкта класуOneClass.

При виході з цієї функції спрацював деструктор, так как копия объекта уничтожается. Кстати, те, що передача об'єкта як параметра за значенням, викликає конструктор копіювання, служить відмінним приводом для передачі об'єкта за посиланням. Це заощадить і час і пам'ять.

В блоці 3 розміщена функціяreturnObjectFunc(). Так як в її тілі прописано створення нового об'єкта класу OneClass– спочатку спрацював конструктор без параметрів. Далі виконується код функції і під час повернення об'єкта в головну функцію main, спрацювавконструктор копіювання.  В кінці, як і має бути, деструктор відпрацював двічі: для об'єкта і для його реальної копії.

В четвертому блоці, під час оголошення і ініціалізації нового об'єкта object2, спрацював конструктор копіювання. При завершенні роботи програми деструктор спрацював для копії об'єкта з четвертого блоку і для об'єкта object1 з першого блоку.

Якщо ж ми закомментіруем /*конструктор копіювання * / в класі і знову запустимо програму – увидим, що конструктор без параметрів спрацює 2 рази, а деструктор – п'ять разів відпрацює.

конструктор копіювання в с ++,  конструктор копії c ++, програмування на с ++ з нуля

В цій ситуації, якби деструктор звільняв пам'ять - в програмі виникла б помилка.

Дуже рекомендую прочитати тему Конструктор копіювання в книзі Стівена Прата “Мова програмування С ++. Лекции и упражнения. 6-видання.” Вона розкрита набагато глибше і включає всі основні нюанси використання конструктора копіювання. Докладно розглянута операція присвоювання =.

6 думки про "Конструктор копіювання в С ++

  1. А чому в коді визначено, невикористаний покажчик?
    int *ptr; // какой-то указатель

    1. Бо хоч якась змінна, член класу, повинна бути визначена в класі?
      Якщо вам не подобається покажчик, визначте змінну типу int.

  2. У 3-му блоці конструктор копіювання не викликається, відповідно і 2-го деструктора немає. Це для компіляторів MinGW, брязкіт(онлайн компілятор ). Для microsoft vc ++ все працює, як і в прикладі.

    1. Тому що там дійсно нет об'єкта, в який потрібно повертати результат.
      Потрібно б записати якось так:

      OneClass object2( returnObjectFunc() );

      Или так:

      OneClass object2 = returnObjectFunc();

Залишити коментар до Салават Скасувати відповідь

Ваша електронна адреса не буде опублікований. Обов'язкові поля позначені * *