# 深拷贝和浅拷贝的区别?
# 简要回答
浅拷贝(Shallow Copy)仅复制对象的成员变量值,包括指针变量的地址;
深拷贝(Deep Copy)会递归复制对象及其所有子对象,包括为指针成员分配新内存并复制内容,创建完全独立的新对象;
在C++中,当类包含指针成员时,浅拷贝会导致两个对象共享同一块内存,而深拷贝则让每个对象拥有自己独立的内存空间;
# 详细回答
拷贝操作主要通过拷贝构造函数和赋值运算符实现,深拷贝与浅拷贝的核心区别在于对指针或动态分配资源的管理方式
- 浅拷贝:
仅复制对象的第一层成员变量
基本数据类型直接复制值
指针类型仅复制指针地址,新旧对象共享同一内存
由编译器生成的默认拷贝构造函数和赋值运算符实现
可能导致双重释放和悬垂指针问题
- 深拷贝:
递归复制对象的所有层级
为指针成员分配新内存并复制内容
新旧对象完全独立,互不影响
需要手动实现拷贝构造函数和赋值运算符
避免内存问题但带来额外性能开销
在C++中,当类管理动态内存(如new分配的资源)时,必须使用深拷贝来避免内存管理问题。
- 打个比方,便于理解:
想象你有一个带锁的箱子(对象),箱子里有贵重物品(指针指向的数据):
浅拷贝就像复制了一把钥匙(指针),新旧钥匙都能打开同一个箱子。
如果一个人用钥匙取走了物品,另一个人会发现箱子空了;
如果两个人都试图锁箱子(释放内存),会导致冲突。
深拷贝则是完全复制了整个箱子及其内容。
新旧箱子各有自己的钥匙和物品,互不干扰,可以安全地各自处理。
# 代码示例
#include <iostream>
using namespace std;
class Deep {
public:
int* data;
Deep(int value) {
data = new int(value);
}
// 自定义拷贝构造函数实现深拷贝
Deep(const Deep& other) {
data = new int(*other.data); // 分配新内存并复制值
}
// 赋值运算符重载实现深拷贝
Deep& operator=(const Deep& other) {
if (this != &other) { // 防止自赋值
delete data; // 释放旧内存
data = new int(*other.data); // 分配新内存并复制值
}
return *this;
}
~Deep() {
delete data; // 安全释放
}
};
int main() {
Deep obj1(10);
Deep obj2 = obj1; // 深拷贝
*obj2.data = 20;
cout << *obj1.data << endl; // 10 (不受影响)
cout << *obj2.data << endl; // 20
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 知识拓展
- 知识图解

- 使用场景
使用浅拷贝: 对象仅包含基本数据类型或POD(Plain Old Data)类型
明确需要共享资源时
性能敏感且确定不会导致问题的情况
使用深拷贝:
对象包含指针或动态分配的资源
需要完全独立的对象副本
多线程环境下避免共享状态
对象生命周期管理复杂的情况
- 面试官可能追问
在STL容器中存储自定义对象时,拷贝语义如何影响容器行为?
STL容器采用值语义存储对象,任何插入操作都会触发拷贝构造(如push_back或insert)
若自定义类包含指针成员且未实现深拷贝,会导致多个对象共享同一内存,引发双重释放问题。
例如,vector
此外,继承场景下,向基类容器插入派生类对象会因拷贝丢失派生类特性("切片问题"),此时建议改用指针容器(如vector<Widget*>)或智能指针。
如何设计一个既能深拷贝又能共享资源的灵活类?
可通过引用计数+写时复制(COW)实现:默认共享资源(浅拷贝),仅在修改时触发深拷贝。
核心是维护共享指针(如shared_ptr)和引用计数,拷贝构造时递增计数,修改前检查计数,若>1则创建新副本并重置计数
← 如何禁止一个类被继承 this指针的原理 →
评论
验证登录状态...