Конструктор копии также вызывается в случае, когда один объект используется для инициализации другого.
Рассмотрим следующую простую программу.
// Вызов конструктора копии для инициализации объекта.
#include <iostream>
#include <cstdlib>
using namespace std;
class myclass {
int *p;
public:
myclass(int i); // обычный конструктор
myclass(const myclass &ob); // конструктор копии
~myclass();
int getval() { return *p; }
};
// Конструктор копии.
myclass::myclass(const myclass &ob)
{
p = new int;
*p = *ob.p; // значение копии
cout << "Выделение p-памяти конструктором копии.\n";
}
// Обычный конструктор.
myclass::myclass(int i)
{
cout << "Выделение p-памяти обычным конструктором.\n";
р = new int;
*р = i;
}
myclass::~myclass()
{
cout << "Освобождение р-памяти.\n";
delete p;
}
int main()
{
myclass a(10); // Вызывается обычный конструктор.
myclass b = a; // Вызывается конструктор копии.
return 0;
}
Результаты выполнения этой программы таковы.
Выделение p-памяти обычным конструктором.
Выделение p-памяти конструктором копии.
Освобождение р-памяти.
Освобождение р-памяти.
Как подтверждают результаты выполнения этой программы, при создании объекта а вызывается обычный конструктор. Но когда объект а используется для инициализации объекта b, вызывается конструктор копии. Использование конструктора копии гарантирует, что объект b выделит для своих членов данных собственную область памяти. Без конструктора копии объект b попросту представлял бы собой точную копию объекта а, а член а.р указывал бы на ту же самую область памяти, что и член b.р.
Следует иметь в виду, что конструктор копии вызывается только в случае выполнения инициализации. Например, следующая последовательность инструкций не вызовет конструктор копии, определенный в предыдущей программе:
myclass а(2), b(3);
// ...
b = а;
Здесь инструкция b = а выполняет операцию присваивания, а не операцию копирования.
Конструктор копии также вызывается при создании временного объекта, который является результатом возвращения функцией объекта. Рассмотрим следующую короткую программу.
/* Конструктор копии вызывается в результате создания временного объекта в качестве значения, возвращаемого функцией.
*/
#include <iostream>
using namespace std;
class myclass {
public:
myclass() { cout << "Обычный конструктор.\n"; }
myclass(const myclass &obj) {cout << "Конструктор копии.\n"; }
};
myclass f()
{
myclass ob; // Вызывается обычный конструктор.
return ob; // Неявно вызывается конструктор копии.
}
int main()
{
myclass a; // Вызывается обычный конструктор.
а = f(); // Вызывается конструктор копии.
return 0;
}
Эта программа генерирует такие результаты.
Обычный конструктор.
Обычный конструктор.
Конструктор копии.
Здесь обычный конструктор вызывается дважды: первый раз при создании объекта а в функции main(), второй — при создании объекта ob в функции f(). Конструктор копии вызывается в момент, когда генерируется временный объект в качестве значения, возвращаемого из функции f().