Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лекции / Конструкторы и деструкторы.docx
Скачиваний:
0
Добавлен:
11.02.2026
Размер:
78.38 Кб
Скачать

Int main ( ) {

My a1 (10); // создаем объект, данное инициализируется 10

My a2 = a1; // создаем объект a2 копию объекта a1- вызов

//конструктора копирования по умолчанию

Print (a1);

/* в стеке создается локальный объект obj - копия объекта a1, вызывается конструктор копирования, значение данного (10) выводится на экран*/

Print (a2); //выводится значение 10

a1.~My ( ); //вызовом деструктора объекта a1 память //выделенная для данного освобождается

Print (a1); //выведется мусор

Print (a2); //выведется мусор

}

Результат программы:

10

10

7853

7853

После вызова деструктора для объекта a1 освобождается динамическая память и в поле данных (*p) объекта a1 содержится теперь мусор (операция delete в процессе возврата в систему памяти затирает эту память).

Но и в поле данных объекта a2 (копии a1) находится теперь тот же мусор.

Результат, безусловно, не верный!

При отсутствии в определении класса конструктора копирования программа будет использовать конструктор копирования по умолчанию следующего вида:

My (My &obj) { p = obj.p; }

Поле данных объекта класса – это указатель p, адресуемый участок памяти, выделенный операцией new в конструкторе с параметрами при создании объекта. Участок памяти предназначен для хранения значения параметра конструктора.

Побитовое копирование объекта a1 дает копирование значения указателя, то есть в поле данных объекта a2 заносится тоже значение указателя, и оказывается, что указатели обоих объектов "указывают" на один и тот же участок памяти (рис. 2.1).

Объект a1

p

10

(*p)

Объектa2

p

Рис. 2.1.Распределение памяти при копировании объектов по умолчанию

При вызове деструктора для объекта a1 освобождается память и затирается единственное данное, общее для двух объектов.

"Уничтожение" объекта a1 привело к уничтожению и его копии a2, в которой находится теперь тот же мусор.

Когда класс содержит поля, являющиеся указателями на динамические участки памяти, для правильного копирования в классе следует определять конструктор копирования вида:

My (const My &obj)

{p = new int; *p = *obj.p;},

в котором выделять память для данного нового объекта, куда и скопировать значение (рис. 2.2).

Объект a1

p

10

Данное (*p)

Объект a2

p

10

Данное (*p)

Рис. 2.2.Распределение памяти при копировании объектов с использованием конструктора копирования

В этом случае объектам a1 и a2 будут принадлежать разные участки памяти для данных. Уничтожение одного из них вызовом деструктора, никак не отразится на существовании другого.

Ниже приведена правильная программа.

#include<iostream>

#include <conio.h>

using namespace std;

class My {

int* p;

public:

My (int a) { p= new int; *p = a; }

My( const My &obj ) //конструктор копирования

{ p = new int; *p = *obj.p; }

int Get ( ) { return *p; } // возвращает значение по адресу указателя

~My() {delete(p);} //освобождает память

};