现代 C++(C++11 及以后)的移动语义(Move Semantics),核心就是一句话:
把一个对象"里的资源"直接转给另一个对象,而不是复制一份。
- 一句话解释
-
拷贝:把对象内容复制一份,两个对象各有一套资源。
-
移动:把原对象的资源直接"抢过来",原对象变成空/无效状态,不复制内存。
适合场景:
对象马上就要被销毁(临时对象、函数返回值),没必要完整拷贝,直接拿走资源更快。
- 关键概念
(1)右值 & 左值
-
左值:有名字、能取地址,能多次使用(如变量)
-
右值:临时值,用完就丢(如 a + b 、 函数返回值 )
移动语义就是专门用来优化右值的。
(2)右值引用 T&&
用来标记"可以被移动"的对象:
cpp
int&& a = 10; // 10 是临时值,用右值引用绑定
(3)移动构造 / 移动赋值
类里新增两个特殊成员函数,接管资源:
cpp
// 移动构造
MyClass(MyClass&& other) noexcept {
// 直接拿走 other 的指针/资源
data_ = other.data_;
other.data_ = nullptr; // 原对象置空
}
// 移动赋值
MyClass& operator=(MyClass&& other) noexcept {
// 释放自身资源
// 拿走 other 资源
// 置空 other
return *this;
}
(4) std::move
把左值强行转成右值,告诉编译器:
"我不用这个对象了,你可以移动它。"
cpp
MyClass a;
MyClass b = std::move(a); // 移动,不是拷贝
- 为什么要用移动语义?
对带堆内存、大容器的对象性能提升巨大:
-
vector<string> 、 string 、 unique_ptr 等
-
函数返回大对象时,不再深拷贝,直接移动
以前 C++98 只能靠返回值优化(RVO),现在移动语义是语言级保证。
- 简单对比示例
cpp
string a = "hello";
string b = a; // 拷贝,慢
string c = move(a); // 移动,快,a 变为空
- 总结
-
移动语义 = 资源转移,而非复制
-
靠 T&& 、移动构造/赋值、 std::move 实现
-
大幅提升临时对象、返回值、容器性能
-
STL 容器(vector/string/map 等)默认都支持移动