Конструктор копирования нужен нам для того, чтобы создавать «реальные» копии объектов класса, а не побитовую копию объекта. Иногда это принципиально важно. Такую «реальную» копию объекта надо создавать в нескольких случаях:
1)когда мы передаем объект в какую-либо функцию в виде параметра;
2)когда какая-либо функция должна вернуть объект класса в результате своей работы;
3)когда мы в главной функции один объект класса инициализируем другим объектом класса.
Например, мы передаем объект в функцию в виде параметра. Функция будет работать не с самим переданным объектом, а с его побитовой копией. Допустим в конструкторе класса, при создании объекта, выделяется определенный объем памяти, а деструктор класса эту память освобождает. Указатель побитовой копии объекта будет хранить тот же адрес памяти, что и оригинальный объект. И, когда при завершении работы функции и уничтожении побитовой копии объекта, сработает деструктор, он обязательно освободит память, которая была занята объектом-оригиналом. В придачу, еще и при завершении работы программы, деструктор сработает повторно и попытается еще раз освободить этот объем памяти, что неизбежно приведет к ошибкам программы. Та же участь постигнет и память, выделенную для указателя объекта, если будет удаляться побитовая копия возвращаемого функцией объекта, и побитовая копия при инициализации объекта класса другим объектом.
Чтобы избежать этих проблем и ошибок существует конструктор копирования. Его работа заключается в том, чтобы создать реальную копию объекта со своей личной выделенной динамической памятью. Синтаксис конструктора копирования следующий: