默认拷贝构造函数只做浅拷贝,类含裸指针时会导致double free崩溃;必须显式实现深拷贝构造、赋值和析构(三/五法则);unique_ptr不可拷贝,shared_ptr共享而非深拷贝;标准容器成员无需手动深拷贝。

拷贝构造函数不写,std::vector 里存指针就崩
默认拷贝构造函数只做浅拷贝,对象里有 int*、char* 或其他裸指针时,两个对象会指向同一块内存。析构时两次 delete,直接 double free or corruption 崩溃。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 只要类里有动态分配的资源(
new出来的内存、打开的文件描述符、malloc的缓冲区),就必须显式定义拷贝构造函数 - 拷贝构造函数第一件事是深拷贝所有指针成员:用
new分配新内存,再用memcpy或循环复制内容 - 别忘了同步实现拷贝赋值运算符(
operator=)和析构函数——三法则(C++11 后叫“三/五法则”)不是建议,是刚需
std::unique_ptr 能自动深拷贝?不能,它根本不允许拷贝
std::unique_ptr 的设计目标就是独占所有权,拷贝构造函数被 = delete 了。试图写 auto b = a; 会报错:use of deleted function ‘std::unique_ptr<t>::unique_ptr(const std::unique_ptr<t>&)’</t></t>。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 想“安全地深拷贝”,改用
std::shared_ptr——但它做的是共享引用计数,不是深拷贝;真正需要深拷贝时,仍得自己 new + copy - 如果真要基于
std::unique_ptr实现深拷贝,必须手动在拷贝构造函数里调用std::make_unique并逐字段复制,例如:data = std::make_unique<int>(*other.data);</int> - 注意:
std::vector<:unique_ptr>></:unique_ptr>拷贝时会触发每个unique_ptr的移动构造,原容器变空——这不是深拷贝,是转移
含 std::string 或 std::vector 成员,还要写深拷贝吗?不用
std::string、std::vector、std::map 等标准容器内部已经实现了正确的深拷贝逻辑。它们的拷贝构造函数会分配新内存并复制元素,不需要你额外干预。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 只要类成员全是标准库类型(或不含裸指针的自定义类型),且没重写过移动语义,用默认拷贝构造函数完全安全
- 但要注意混合场景:比如类里既有
std::vector<int></int>又有int*,那std::vector部分自动深拷贝,int*部分必须手写——漏掉后者,照样崩溃 - 用
clang++ -Weffc++或g++ -Wextra编译能提醒你“class has pointer data members but no copy constructor”这类隐患
移动构造函数写了,拷贝构造函数还用写吗?看需求
写了移动构造函数不会禁用默认拷贝构造函数,但如果你显式定义了移动构造函数或移动赋值,编译器就不会自动生成拷贝版本(C++11 规则)。此时若没写拷贝构造函数,又尝试拷贝,就会编译失败。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 如果类确实不该被拷贝(比如管理唯一资源),就显式删除:
MyClass(const MyClass&) = delete; - 如果既要移动又要拷贝,两个都得写清楚,别依赖编译器生成——尤其当类里有指针时,生成的拷贝构造函数仍是浅拷贝
- 检查是否意外禁用了拷贝:搜索代码中有没有
= default或= delete在拷贝相关函数上,IDE 跳转到定义最可靠
深拷贝真正的复杂点不在语法,而在于“所有权边界”是否清晰。一个 new 出来的指针,到底归谁释放?多个函数、多个容器、多线程之间怎么传递?这些问题没理清,光把拷贝构造函数写对也没用。









