Когда нам следует писать собственный конструктор копирования на C++?
Конструктор копирования — это функция-член, которая инициализирует объект, используя другой объект того же класса. (см. эту статью для справки).
Когда мы должны написать собственный конструктор копирования?
Компилятор C++ предоставляет конструктор копирования по умолчанию (и оператор присваивания) с классом. Когда мы не предоставляем реализацию конструктора копирования (и оператора присваивания) и пытаемся инициализировать объект с уже инициализированным объектом того же класса, тогда вызывается конструктор копирования и копирует членов класса один за другим в целевой объект.
Но проблема с конструктором копирования по умолчанию (и оператором присваивания):
- Когда у нас есть члены, которые динамически инициализируются во время выполнения, конструктор копирования по умолчанию копирует этот член с адресом динамически выделенной памяти, а не реальной копией этой памяти.
- Теперь оба объекта указывают на одну и ту же память, и изменения в одном отражаются в другом объекте.
- Кроме того, основной катастрофический эффект заключается в том, что когда мы удаляем один из этих объектов, другой объект по-прежнему указывает на ту же память, которая будет оборванным указателем, и утечка памяти также является возможной проблемой при таком подходе.
Таким образом, нам нужно определить собственный конструктор копирования только в том случае, если объект имеет указатели или какое-либо выделение ресурса во время выполнения, например дескриптор файла, сетевое соединение и т. д.
Конструктор по умолчанию выполняет только поверхностное копирование.
Глубокое копирование возможно только с помощью пользовательского конструктора копирования. В определяемом пользователем конструкторе копирования мы удостоверяемся, что указатели (или ссылки) скопированных объектов указывают на новые ячейки памяти.
Следовательно, в таких случаях мы всегда должны писать собственный конструктор копирования (и оператор присваивания).
Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по теме, обсуждаемой выше.