Когда вызывается конструктор копирования?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Когда вызывается конструктор копирования?
Конструктор копирования (copy constructor) — это специальный конструктор, который создаёт новый объект как копию существующего объекта того же класса. Он автоматически вызывается компилятором в следующих ситуациях:
1. Инициализация объекта другим объектом
class MyClass {
public:
MyClass(const MyClass& other) { // copy constructor
std::cout << "Copy constructor called\n";
}
};
MyClass obj1;
MyClass obj2 = obj1; // вызов copy constructor
MyClass obj3(obj1); // вызов copy constructor
2. Передача объекта по значению в функцию
void processObject(MyClass obj) {
// obj — копия переданного аргумента
}
MyClass obj1;
processObject(obj1); // вызов copy constructor
3. Возврат объекта из функции по значению
MyClass createObject() {
MyClass local;
return local; // вызов copy constructor (без RVO/NRVO)
}
MyClass obj = createObject(); // вызов copy constructor
4. Использование в контейнерах STL
std::vector<MyClass> vec;
MyClass obj;
vec.push_back(obj); // вызов copy constructor
vec.insert(vec.begin(), obj); // вызов copy constructor
5. Явное копирование
MyClass obj1;
MyClass obj2;
obj2 = obj1; // вызов operator= (assignment), не copy constructor
Важные замечания
RVO и NRVO (Return Value Optimization / Named Return Value Optimization) — современные компиляторы оптимизируют копирование при возврате из функции, поэтому copy constructor может НЕ вызваться.
Если конструктор копирования не определён явно, компилятор автоматически генерирует default copy constructor, который выполняет поверхностное копирование (shallow copy) — копирует все члены класса побитово. Это может привести к проблемам с динамической памятью:
class BadClass {
int* ptr;
public:
BadClass(int value) { ptr = new int(value); }
~BadClass() { delete ptr; } // двойное удаление!
};
Для классов с динамической памятью необходимо определить собственный copy constructor:
class GoodClass {
int* ptr;
public:
GoodClass(const GoodClass& other) {
ptr = new int(*other.ptr); // глубокое копирование
}
};
Move семантика (C++11+) — для оптимизации копирования используют move constructor и rvalue references, чтобы избежать ненужного копирования временных объектов.