默认拷贝构造函数执行浅拷贝,仅复制指针地址;深拷贝需手动分配内存、复制内容、更新指针,并同步实现赋值运算符与析构函数,推荐使用std::vector等RAII容器替代裸指针。
当你没写 MyClass(const MyClass& other),编译器自动生成的拷贝构造函数会逐字节复制成员变量。如果类里有指针(比如 int* data),它只复制指针地址,不复制指针指向的内容——两个对象的 data 指向同一块内存。析构时各自 delete 同一块内存,触发 double free 或崩溃。
实现深拷贝的关键动作就三步:申请新内存 → 复制原数据 → 更新指针。不能依赖 m 或默认赋值,必须显式控制资源所有权。
new 分配和原对象等大的内存std::copy 把原对象的数据逐个拷贝过去std::mutex 等需单独处理(通常不能拷贝,应禁用或重置)class Buffer {
public:
Buffer(const Buffer& other) : size_(other.size_) {
data_ = new char[size_];
std::copy(other.data_, other.data_ + size_, data_);
}
~Buffer() { delete[] data_; }
private:
char* data_;
size_t size_;
};否则 a = b 仍走默认浅拷贝,导致悬空指针或内存泄漏。赋值运算符要处理自赋值、释放旧资源、再深拷贝新资源。
if (this == &other) return *this;
delete[] data_ 清理当前内存swap + 临时对象),自动处理异常安全和自赋值手动管理 new/delete 极易出错。用 std::vector、std::string、std::unique_ptr 后,编译器生成的拷贝构造函数天然就是深拷贝(对 vector 是元素级拷贝,对 unique_ptr 是移动而非拷贝)。
std::vector data_; → 拷贝构造自动深拷贝所有元素std::unique_ptr data_; → 不可拷贝,强制你思考所有权,避免误用深拷贝真正麻烦的从来不是“怎么写”,而是“要不要写”——多数时候,用对容器就能绕过整个问题。但一旦用了裸指针,就必须把拷贝构造、赋值、析构三个函数一起写全,缺一不可。