C++之默认拷贝函数
C++ 会在以下情况自动生成默认拷贝构造函数,即拷贝构造函数未被显式定义时,编译器为类创建一个浅拷贝的构造函数:
1. 类中没有用户定义的拷贝构造函数
如果类中没有提供拷贝构造函数,编译器会为类生成一个默认的拷贝构造函数。这种构造函数会执行成员逐个拷贝的操作,即按成员的类型进行浅拷贝。
2. 类的成员没有被禁止拷贝
默认拷贝构造函数不会为某些特殊成员生成,比如:
- 有些成员类型明确禁止拷贝(如
std::unique_ptr
),在这种情况下,编译器不会生成默认拷贝构造函数。 - 如果类的成员包含某些无法拷贝的对象,拷贝构造函数会被禁止(例如,类中包含了
delete
掉拷贝构造函数的对象)。
默认拷贝构造函数的行为:
默认的拷贝构造函数会做浅拷贝,逐个成员变量按其类型进行复制操作。
- 基本类型(如
int
、double
等)会直接拷贝其值。 - 指针类型:只拷贝指针的地址,导致源对象与目标对象共享同一块内存资源。
默认拷贝构造函数生成的规则:
- 没有用户定义的拷贝构造函数:如果类中没有定义任何拷贝构造函数,编译器会生成一个默认的拷贝构造函数。
- 没有其他操作删除拷贝构造函数:如果程序员显式
delete
了拷贝构造函数,编译器就不会自动生成默认构造函数。
示例:
class MyClass {
public:
int x;
MyClass(int a) : x(a) {}
// 编译器将自动生成一个默认的拷贝构造函数
};
int main() {
MyClass obj1(10);
MyClass obj2 = obj1; // 调用默认拷贝构造函数
std::cout << obj2.x << std::endl; // 输出 10
return 0;
}
在这个例子中,MyClass
没有定义拷贝构造函数,因此编译器会生成一个默认的拷贝构造函数,执行浅拷贝。
禁止拷贝构造的情况:
有些情况下,编译器会禁止生成默认拷贝构造函数。例如,使用了 std::unique_ptr
或者显式 delete
拷贝构造函数时:
class MyClass {
public:
std::unique_ptr<int> ptr;
MyClass(int val) : ptr(new int(val)) {}
// 显式删除拷贝构造函数
MyClass(const MyClass& obj) = delete;
};
int main() {
MyClass obj1(10);
MyClass obj2 = obj1; // 错误,拷贝构造函数被删除
return 0;
}
总结:
- C++ 在没有显式定义拷贝构造函数时,会自动生成一个默认拷贝构造函数。
- 默认拷贝构造函数会执行浅拷贝,逐个复制对象的成员。
- 如果类中的成员或特定情况禁止拷贝,编译器不会生成默认拷贝构造函数。