C++ 新特性 | C++ 11 | 移动语义
文章目录
- **C++ 移动语义(通俗版)**
- **1. 为什么需要移动语义?**
- **2. 怎么“偷”?——右值引用(`&&`)**
- **3. 如何实现移动语义?——移动构造函数/赋值**
- **4. 什么时候触发移动?**
- **5. 移动 vs 拷贝**
- **一句话总结**
C++ 移动语义(通俗版)
1. 为什么需要移动语义?
传统拷贝(=
)会复制整个对象,但如果对象很大(如 vector<string>
),拷贝开销大。
移动语义的核心思想:“偷资源”,避免不必要的深拷贝,提升性能。
2. 怎么“偷”?——右值引用(&&
)
- 右值(临时对象、字面量等) 的生命周期短,可以安全“偷”它的资源。
- 右值引用
&&
用来绑定右值,表示“这个值可以移动”。
示例:
std::string s1 = "Hello";
std::string s2 = std::move(s1); // 把 s1 的资源“偷”给 s2
s1
变成空(资源被移动),s2
直接接管原内存,没有拷贝。
3. 如何实现移动语义?——移动构造函数/赋值
类需要定义移动构造函数和移动赋值运算符:
class MyObject {
public:
// 移动构造函数(参数是右值引用)
MyObject(MyObject&& other) noexcept {
data_ = other.data_; // 直接“偷”指针
other.data_ = nullptr; // 原对象置空
}
// 移动赋值运算符
MyObject& operator=(MyObject&& other) noexcept {
if (this != &other) {
delete data_; // 释放自己的资源
data_ = other.data_; // “偷”对方的资源
other.data_ = nullptr;
}
return *this;
}
private:
int* data_; // 假设管理动态内存
};
关键点:
- 直接“窃取”资源(如指针),避免深拷贝。
- 把原对象的资源置空(防止重复释放)。
4. 什么时候触发移动?
- 显式移动:
std::move(obj)
强制转成右值引用。 - 隐式移动:函数返回临时对象时(编译器优化)。
示例:
std::vector<int> createBigVector() {
std::vector<int> v = {1, 2, 3, 4, 5};
return v; // 编译器可能优化为移动(而非拷贝)
}
auto v = createBigVector(); // 移动构造,无拷贝
5. 移动 vs 拷贝
拷贝 | 移动 | |
---|---|---|
操作 | 深复制(完整备份) | “偷”资源(直接接管) |
开销 | 高(内存、时间) | 低(仅指针交换) |
原对象 | 保持不变 | 被置空(资源转移) |
一句话总结
移动语义通过 &&
和 std::move
“偷”临时对象的资源,避免深拷贝,提升性能。
适用于管理动态内存的类(如 vector
、string
、自定义资源类)。