Конструктор копирования

Конструктор копирования создает копию объекта в оперативной памяти с помощью другого объекта того же класса. В качестве параметра этот кон­структор получает ссылку на объект, копию которого необходимо создать. Для конструктора копирования необходимо указать прототип следующего формата:

public:имя_класса (имя_класса &);

Для класса CBook конструктор копирования объявляется в спецификации класса со следующим прототипом:

СВоок (СВоок &);

 

Пример конструктора копирования   

СВоок:: СВоок (СВоок &о): m_year (o. m_year) {

strcpy_s (m_author, strlen (o.m_author) + 1, o.m_author);

m_pTitle = new char [strlen (o.m_pTitle) + 1 ];

strcpy_s (m_pTitle, strlen (o. m_pTitle) + 1, o. m_pTitle);

}

 

В результате работы конструктора копирования будет постро­ен новый объект-книга, все члены-данные которого получат значения дан­ных, принадлежащих копируемому объекту о, переданному по ссылке. Чтобы присвоить значение названия книги вновь создаваемому объекту, нужно сна­чала выделить необходимый блок памяти при помощи оператора new.

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

  // есорусоn.срр

// инициализация объектов с помощью копирующего конструктора

#include <iostream>

using namespace std;

//////////////////////////////////////////////////////////

class Distance    // длина в английской системе

{

private:

int feet;

float inches;

public:

// конструктор без аргументов

Distance(): feet(0), inches(0.0) { }

// конструктора с одним аргументом нет!

// конструктор с двумя аргументами

Distance(int ft, float in): feet(ft), inches(in) { }

void getdist()      // ввод длины пользователем

{

cout << "\nВведите число футов ";

cin >> feet;

cout << "Введите число дюймов: ";

cin >> inches;

}

void showdist() // вывод длины

{ cout << feet << "\'-" << inches << "'\'"; }

};

//////////////////////////////////////////////////////////

int main()

{

Distance dist1(11,6.25); // конструктор с двумя аргументами

Distance dist2(dist1); // два конструктора с одним аргументом

Distance dist3 = dist1;

// вывод всех длин

cout <<"\ndistl - ";

dist1.showdist();

cout <<"\ndist2 - ";

dist2.showdist();

cout <<"\ndist3 - ";

dist3.showdist();

cout << endl;

return 0;

}

Мы инициализировали объект distl значением 11’-6.25" при помощи конст­руктора с двумя аргументами. Затем мы определяем еще два объекта класса Distance с именами dist2 и dist3, оба из которых инициализируются значением объекта distl. Возможно, вам покажется, что в данном случае должен был вы­зваться конструктор с одним аргументом, но поскольку аргументом являлся объект того же класса, что и инициализируемые объекты, были предприняты иные действия. В обоих случаях был вызван копирующий конструктор по умол­чанию. Объект dist2 инициализирован при помощи оператора

Distance dist2(distl):

Действие копирующего конструктора по умолчанию сводится к копирова­нию значений полей объекта distl в соответствующие поля объекта dist2. Как это ни удивительно, но идентичные действия для пары объектов distl и dist3 вы­полняются при помощи оператора

Distance dist3 = distl;

Можно подумать, что данный оператор выполняет операцию присваивания, но это не так. Здесь, как и в предыдущем случае, вызывается конструктор копи­рования по умолчанию. Оба оператора выполняют одинаковые действия и рав­ноправны в использовании. Результат работы программы выглядит следующим образом:

distl = 11'-6.25"

dist2 = 11"-6.25"

dist3 -=11'-6.25"

Видим, что объекты dist2 и dist3 действительно имеют те же значения, что и объект distl.

 

Деструктор

Деструктор (destructor) — специальный метод класса, используемый для разрушения объектов класса. Имя деструктора совпадает с именем конструк­тора (именем класса), которому предшествует символ тильда ~. Он всегда имеет открытый спецификатор доступа и не имеет ни типа, ни параметров. Деструктор управляет уничтожением объекта из оперативной памяти.

Вызывается деструктор автоматически при разрушении объекта. Если объект создавался динамически через указатель при помощи оператора new, то для уничтожения такого объекта следует использовать оператор delete для ука­зателя.

Типовым использованием деструктора является освобождение динамической памяти, которая ранее была выделена конструктором.

В отличие от конструктора, деструктор не перегружается и может быть в классе только один. Лучше всегда определять деструктор класса, даже если он не производит никаких действий и имеет пустое тело.

Объявление деструктора имеет следующий формат:

public:~имя_класса ();

Например, для класса Cвоок прототип деструктора в спецификации класса имеет вид:

~СВоок ();

 

СВоок:: ~СВоок () {delete [ ] m_pTitle;      }

 

Результатом действия деструктора ~СВоок () является освобождение блока памяти с начальным адресом из itLpTitle, выделенного ранее конструктором класса.

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: