拷贝构造函数是C++中一种特殊的构造函数,它的参数是本类对象的引用(通常是 const 修饰),用于用已有的对象来初始化新创建的对象。
1. 什么时候会触发它?
编译器会在以下 3种情况 自动调用拷贝构造函数(而不是赋值运算符):
-
情况1(最直接):用一个对象初始化另一个对象,如 ClassA b = a; 或 ClassA b(a);。
-
情况2:函数的参数是按值传递(传参时实参拷贝给形参)。
-
情况3:函数返回一个对象(返回值拷贝给接收方)。
2. 默认行为 vs 自定义行为
-
默认拷贝构造(浅拷贝):如果你不写,编译器会自动生成一个,它会把源对象的成员变量逐字节复制过去。
-
自定义拷贝构造(深拷贝):如果类里有指针成员并动态分配了内存(堆内存),默认浅拷贝会导致两个对象指向同一块内存,析构时会重复释放(崩溃)。此时必须自定义拷贝构造,为新对象分配独立的内存。
#include <iostream>
using namespace std;
class NumberBox {
private:
int* data; // 指针成员,指向堆内存
public:
// 1. 普通构造函数
NumberBox(int value) {
data = new int(value); // 在堆上分配内存
cout << "普通构造: " << value << endl;
}
// 2. 拷贝构造函数(深拷贝)⭐ 核心
NumberBox(const NumberBox& other) {
// 为新对象分配独立的内存,再把值拷过来
data = new int(*other.data);
cout << "拷贝构造触发! 值: " << *data << endl;
}
// 3. 析构函数(释放内存)
~NumberBox() {
cout << "析构, 释放: " << *data << endl;
delete data;
}
// 获取值
int getValue() const {
return *data;
}
};
// 4. 测试函数:按值传递参数(会触发拷贝构造)
void printBox(NumberBox box) {
cout << "函数内打印: " << box.getValue() << endl;
}
// 5. 测试函数:按值返回对象(会触发拷贝构造)
NumberBox createBox(int val) {
NumberBox temp(val); // 普通构造
return temp; // 返回时触发拷贝构造(拷贝给外部接收者)
}
int main() {
cout << "— 情况1: 初始化 —" << endl;
NumberBox a(10); // 普通构造
NumberBox b = a; // 拷贝构造(用a初始化b)
cout << "\\n— 情况2: 传参 —" << endl;
printBox(a); // 传参时,实参a拷贝给形参box
cout << "\\n— 情况3: 返回值 —" << endl;
NumberBox c = createBox(20); // 接收返回值,触发拷贝构造
cout << "\\n— 程序结束,准备析构 —" << endl;
return 0;
}
网硕互联帮助中心



评论前必须登录!
注册