建设法律法规文本查询网站阿里云盘资源搜索引擎
目录
一、默认拷贝构造函数的陷阱(浅拷贝)
二、自定义拷贝构造函数(深拷贝)
三、深拷贝与浅拷贝对比
四、注意事项
一、默认拷贝构造函数的陷阱(浅拷贝)
class MyString {
private:char* ptr; // 指向动态分配的内存
public:// 默认拷贝构造函数(按位拷贝)MyString(const MyString &st) : ptr(st.ptr) {} // 浅拷贝:仅复制指针地址
};
问题分析:
-
浅拷贝本质:直接复制指针值,新旧对象共享同一块内存。
-
致命缺陷:
-
重复释放:析构时多个对象尝试释放同一内存,导致崩溃。
-
悬空指针:一个对象释放内存后,其他对象指针失效。
-
数据篡改:通过任意对象修改内容,影响所有共享对象。
-
二、自定义拷贝构造函数(深拷贝)
class MyString {
private:char* ptr;
public:// 构造函数:动态分配内存MyString(const char* str = nullptr) {if (str) {int len = strlen(str);ptr = new char[len + 1];strcpy(ptr, str);} else {ptr = new char[1];*ptr = '\0';}}// 深拷贝构造函数MyString(const MyString& st) {if (st.ptr) {int len = strlen(st.ptr);ptr = new char[len + 1]; // 独立分配新内存memcpy(ptr, st.ptr, len + 1); // 复制内容而非指针(比strcpy更高效)} else {ptr = nullptr; // 处理空指针边界条件}}// 析构函数:安全释放内存~MyString() {delete[] ptr; // delete[] 匹配 new[]ptr = nullptr; // 避免悬空指针}
};
关键改进:
-
独立内存分配:每个对象持有独立内存块。
-
内容复制:使用
memcpy
或strcpy
确保数据完整性。 -
边界处理:明确处理空指针输入场景。
三、深拷贝与浅拷贝对比
特性 | 浅拷贝 | 深拷贝 |
---|---|---|
内存共享 | 是(多个对象指向同一内存) | 否(每个对象拥有独立内存) |
安全性 | 低(重复释放/悬空指针) | 高(内存隔离) |
适用场景 | 无动态内存管理的简单类型(如int) | 含指针/动态资源的类(如字符串) |
实现复杂度 | 自动生成(无需编码) | 需显式实现拷贝构造/赋值运算符 |
四、注意事项
-
三人行
若自定义拷贝构造函数、拷贝赋值运算符或析构函数中的一个,必须显式实现三者。 -
优先使用
std::string
:
避免手动管理内存,直接利用标准库的深拷贝能力。 -
深拷贝工具优化:
-
使用
memcpy
替代strcpy
提升大内存块复制效率。 -
添加
nullptr
检查防止未定义行为。
-