c++中如何实现深拷贝_c++拷贝构造函数与深拷贝区别【详解】

11次阅读

默认拷贝构造函数执行浅拷贝,仅复制指针地址;深拷贝需手动分配内存、复制内容、更新指针,并同步实现赋值运算符析构函数,推荐使用std::vector等RaiI容器替代裸指针。

c++中如何实现深拷贝_c++拷贝构造函数与深拷贝区别【详解】

拷贝构造函数默认是浅拷贝

当你没写 MyClass(const MyClass& other),编译器自动生成的拷贝构造函数会逐字节复制成员变量。如果类里有指针(比如 int* data),它只复制指针地址,不复制指针指向的内容——两个对象data 指向同一块内存。析构时各自 delete 同一块内存,触发 double free 或崩溃。

深拷贝必须手动分配新内存并复制内容

实现深拷贝的关键动作就三步:申请新内存 → 复制原数据 → 更新指针。不能依赖 memcpy 或默认赋值,必须显式控制资源所有权。

  • 在拷贝构造函数里用 new 分配和原对象等大的内存
  • 循环std::copy 把原对象的数据逐个拷贝过去
  • 记得同步拷贝其他资源:文件句柄、socket、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 + 临时对象),自动处理异常安全和自赋值

现代 c++ 更推荐用 RAII 容器替代裸指针

手动管理 new/delete 极易出错。用 std::vectorstd::Stringstd::unique_ptr 后,编译器生成的拷贝构造函数天然就是深拷贝(对 vector 是元素级拷贝,对 unique_ptr 是移动而非拷贝)。

立即学习C++免费学习笔记(深入)”;

  • std::vector data_; → 拷贝构造自动深拷贝所有元素
  • std::unique_ptr data_; → 不可拷贝,强制你思考所有权,避免误用
  • 裸指针只在极少数性能敏感且必须绕过容器开销的场景才保留

深拷贝真正麻烦的从来不是“怎么写”,而是“要不要写”——多数时候,用对容器就能绕过整个问题。但一旦用了裸指针,就必须把拷贝构造、赋值、析构三个函数一起写全,缺一不可。

text=ZqhQzanResources