这三个是 C++11 最重要的特性,核心目的是减少不必要的内存拷贝,提升程序性能。我用最清晰、最实用的方式给你讲透,包含定义、代码、区别和用法。
前置知识:左值 & 右值
左值:可以取地址、有名字的变量(如 int a=10; a 是左值)
右值:临时值,不能取地址、用完就销毁(如 10、函数返回值)
C++11 用 && 表示右值引用,专门绑定临时对象,这是移动语义的基础。
右值引用 = 专门用来偷临时对象资源的。
1. 移动构造函数 (Move Constructor)
作用:
把一个临时右值对象的资源直接转移给新对象,不拷贝内存,速度极快。
类名(类名&& 其他对象) noexcept;
- 移动构造不分配新内存,直接接管临时对象的资源
- 必须把原对象的指针置空,避免双重释放
- 比拷贝构造快成千上万倍(尤其大对象 / 容器)
2. 移动赋值运算符 (Move Assignment)
类名& operator=(类名&& 其他对象) noexcept;
3. 完美转发 (Perfect Forwarding)
作用:
在函数模板中,完整保留参数的左值 / 右值属性,原封不动转发给其他函数,不产生额外拷贝。
解决痛点:
模板传参时,右值容易被变成左值,导致调用拷贝而非移动。
三者对比:
| 特性 | 移动构造 | 移动赋值 | 完美转发 |
|---|---|---|---|
| 用途 | 创建新对象时转移资源 | 给已有对象转移资源 | 函数模板保持参数类型不变地转发 |
| 语法 | A(A&&) |
A& operator=(A&&) |
std::forward<T>() |
| 性能 | 极快,无拷贝 | 极快,无拷贝 | 零开销,无拷贝 |
| 适用对象 | 临时右值 | 临时右值 | 任意类型(左值 + 右值) |
| 必须置空源对象? | 是 | 是 | 否 |