Копирующий конструктор позволяет производить копирование одного объект класса в другой объект того же класса. Эта операция необходима в следующих случаях:
– Вновь создаваемый объект класса должен стать копией уже имеющегося объекта (инициализация копированием).
– Два объекта класса созданы ранее, нужно скопировать один объект в другой, например при выполнении операции присваивания.
– Если аргумент функции или возвращаемое значение является объектом класса, то при передаче параметров и возвращаемых значений неявно вызывается конструктор копирования.
Если программист не задает явно конструктор копирования, то компилятор создает его автоматически. В этом случае действуют правила копирования по- умолчанию, то есть копируются все нестатические поля класса.
В следующем примере работает копирование по-умолчанию.
#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
using namespace std;
class MyStr
{ ...
...
};------- конец определения класса MyStr
int MyStr::count=0;
int MyStr::num=0;
int main(int argc, char* argv[])
{ MyStr c1("1_string"); // создание объекта с1
cout<<endl<<"Объект с1"<<endl;
c1.display();
MyStr c2(c1); // создание объекта с2 (инициализация копированием)
cout<<"Объект с2"<<endl;
c2.display();
MyStr c3=c1; // создание объекта с3 и присвоение ему значения с1
cout<<"Объект с3"<<endl;
c3.display();
system ("pause");
return 0;
}
Строка MyStr c2(c1) вызывает конструктор копирования (во вновь создаваемый объект с2 записывается информация из с1). В строке MyStr c3=c1 оператор присваивания вызывает конструктор копирования.
Анализируя результаты работы можно сделать вывод, что копирование по-умолчанию корректно работает с нестатическим полем buf, статические же поля никак не изменяются.
Для того, чтобы получить правильный результат, необходимо определить копирующий конструктор, который правильно работает со всеми полями класса.
Добавим в класс MyStr копирующий конструктор:
MyStr(MyStr& s)
{buf= new char[strlen(s.buf)+1];
num++;
count++;
nn=num;
strcpy(buf, s.buf);
}
В результате программа полностью корректно работает.
В копировании принимают участие два объекта класса, причем один объект активизирует копирование, а другой играет пассивную роль.
MyStr c2(c1); - активный объект с2, пассивный с1
MyStr c3=c1; - активный объект с3, пассивный с1
Обратите внимание на тип аргумента копирующего конструктора – это всегда ссылка на свой класс, ссылка на пассивный объект.
Работа копирующего конструктора при передаче объекта класса в качестве параметра функции (и возврате из функции объекта класса) будет рассмотрена позднее.