在 C++ 中,一个类的对象在"创建"和"赋值"时,
编译器可能会调用四种特殊函数来决定对象的行为:
- 拷贝构造函数(Copy Constructor)
- 拷贝赋值运算符(Copy Assignment)
- 移动构造函数(Move Constructor)
- 移动赋值运算符(Move Assignment)
这四个函数统称为:对象语义控制函数。
它们的本质是两件事:
复制资源 还是 转移资源
一、拷贝构造函数(Copy Constructor)
1. 定义
拷贝构造函数是一种特殊的构造函数,
用于 用一个已存在对象,创建一个新的同类对象。
2. 标准格式
cpp
类名(const 类名& other);
示例:
cpp
Box(const Box& other);
3. 特点
- 函数名与类名相同
- 没有返回值
- 参数必须是同类引用
const T& - 用于"新对象出生"
- 复制数据或资源
4. 最小示例
cpp
Box a(10);
Box b = a; // 调用拷贝构造
5. 一句话记忆
拷贝构造 = 用旧对象,生一个新对象
二、拷贝赋值运算符(Copy Assignment)
1. 定义
拷贝赋值运算符是对 = 运算符的重载函数,
用于 把一个对象的内容复制到另一个已存在对象中。
2. 标准格式
cpp
类名& operator=(const 类名& other);
示例:
cpp
Box& operator=(const Box& other);
3. 特点
- 有返回值(类引用)
- 函数名为
operator= - 参数为
const T& - 用于对象已经存在时
4. 最小示例
cpp
Box a(10);
Box b(0);
b = a; // 调用拷贝赋值
5. 一句话记忆
拷贝赋值 = 用旧对象,改一个旧对象
三、移动构造函数(Move Constructor)
1. 定义
移动构造函数用于 把一个临时对象(右值)的资源转移给新对象 ,
避免深拷贝带来的性能损耗。
2. 标准格式
cpp
类名(类名&& other);
示例:
cpp
Box(Box&& other);
3. 特点
- 参数为右值引用
T&& - 转移资源而不是复制
- 常见于函数返回值、临时对象
4. 最小示例
cpp
Box b = Box(10); // 可能触发移动构造
5. 一句话记忆
移动构造 = 把临时对象的资源搬过来
四、移动赋值运算符(Move Assignment)
1. 定义
移动赋值用于 把一个临时对象的资源转移给一个已经存在的对象。
2. 标准格式
cpp
类名& operator=(类名&& other);
示例:
cpp
Box& operator=(Box&& other);
3. 特点
- 参数为
T&& - 转移资源
- 用于已存在对象
4. 最小示例
cpp
Box a(10);
a = Box(20); // 可能触发移动赋值
5. 一句话记忆
移动赋值 = 把临时对象的资源搬给旧对象
五、四大函数对照总表
| 类型 | 作用 | 格式 | 场景 |
|---|---|---|---|
| 拷贝构造 | 新对象复制 | T(const T&) |
T b = a |
| 拷贝赋值 | 旧对象复制 | T& operator=(const T&) |
b = a |
| 移动构造 | 新对象搬资源 | T(T&&) |
T b = T() |
| 移动赋值 | 旧对象搬资源 | T& operator=(T&&) |
b = T() |
六、终极记忆口诀
cpp
拷贝构造:生一个我(复制)
拷贝赋值:改一个我(复制)
移动构造:生一个我(搬资源)
移动赋值:改一个我(搬资源)
七、工程中的意义(一句话版)
拷贝:我再买一份资源
移动:我把资源给你,我不要了
当类里有堆内存、文件句柄、锁、socket 等资源时,
这四个函数就决定了对象是否安全、是否高效。
这就是 C++ 对象模型的核心之一。