1. 什么是右值?
- 左值:有名字,可以找到它放在哪(能取地址的)。
比如:
int a = 10; // a 是左值
- 右值:临时的、没名字的,用完就没了的东西。
比如:
int b = a + 5; // a+5 是个临时值,就是右值
int c = 100; // 100 这个字面量也是右值
你可以理解为:
左值像“家里有户口的人”,长期住在内存里。
右值像“旅馆里住一晚的游客”,用完就要走。
2. 右值引用(T&&)是干嘛的?
右值引用就是专门“接住”这种临时对象的手段。
比如:
void foo(int&& x) {cout << x << endl;
}foo(10); // 可以
这里 10 是个右值(临时的常量),普通引用 int& 接不住,但 int&& 可以。
所以右值引用的作用是:接管临时值,让它不至于马上消失,还能被高效利用。
3. 为什么需要右值引用?
主要是为了解决 效率问题,特别是“拷贝 vs. 移动”。
拷贝(慢)
string s1 = "hello world";
string s2 = s1; // 拷贝,需要新建一份内存
移动(快)
string s1 = "hello world";
string s2 = std::move(s1); // 移动,直接把资源“过户”,不用再拷贝
右值引用就是移动语义的基础。
就像二手房交易:
拷贝 = 再盖一栋一样的房子,成本高。
移动 = 直接把钥匙交给你,省事。
4. 用法直观举例
class MyVector {int* data;size_t size;
public:// 构造函数MyVector(size_t n): size(n) {data = new int[n];cout << "构造" << endl;}// 拷贝构造MyVector(const MyVector& other): size(other.size) {data = new int[size];memcpy(data, other.data, size * sizeof(int));cout << "拷贝构造" << endl;}// 移动构造(右值引用)MyVector(MyVector&& other): size(other.size), data(other.data) {other.data = nullptr; // 交出资源cout << "移动构造" << endl;}
};
使用:
MyVector v1(100);
MyVector v2 = v1; // 触发拷贝构造(慢)
MyVector v3 = MyVector(50); // 触发移动构造(快,直接“过户”)