深拷贝与浅拷贝的区别仅在类含指向堆内存的裸指针(如char、int)时体现:浅拷贝仅复制指针值,导致共享堆内存;深拷贝则调用new/malloc重新分配堆内存并复制内容,确保资源独立。

深拷贝和浅拷贝的区别,只在类里有「指向堆内存的裸指针」(比如 char*、int*)时才真正生效;没有这类成员,编译器默认的浅拷贝完全够用,也根本不存在“区别”问题。
看拷贝构造函数有没有重新分配堆内存
判断是深还是浅,核心就一条:拷贝时是否对指针成员调用了 new / malloc 并用 memcpy 或赋值操作复制了它指向的数据。
- 如果只是写
other.ptr直接赋给新对象的ptr→ 浅拷贝 - 如果写了
ptr = new int(*other.ptr)或ptr = new char[strlen(other.ptr)+1]; strcpy(ptr, other.ptr);→ 深拷贝 - 没写拷贝构造函数?那编译器生成的就是浅拷贝(逐字节复制,包括指针值)
运行时崩溃是浅拷贝最直接的信号
程序在第二次析构时报 double free or corruption,或者访问已释放内存(segmentation fault),基本可以断定是浅拷贝导致的指针共享。
- 两个对象的指针成员地址相同(用
printf("%p", obj.ptr)对比)→ 共享堆内存 - 第一个对象析构后,第二个对象的
ptr变成悬挂指针,再访问或delete就崩 - 用
std::string或std::vector替代裸指针,能自动规避这个问题(它们内部已实现深拷贝)
赋值运算符也要同步处理,不能只改拷贝构造函数
只重载了拷贝构造函数,但没重载 operator=,照样会出问题——因为 = 默认也是浅拷贝。
- 赋值运算符里漏掉自赋值检查(
if (this == &other) return *this;)→ 自赋值时可能先delete再new,造成空指针解引用 - 没释放原对象堆内存就直接
new→ 内存泄漏 - 建议按“规则之三”(Rule of Three):只要写了拷贝构造函数、析构函数、赋值运算符中的任意一个,另外两个通常也得写
最容易被忽略的是:深拷贝不是“多写几行代码”的事,而是整个资源生命周期管理逻辑的转折点。一旦引入裸指针,你就得全程负责分配、复制、释放——少一步,崩溃就在运行时等着。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











