右值引用是C++11引入的&&类型,专用于绑定将亡值和纯右值,支撑移动语义与完美转发;它区别于const左值引用,允许修改源对象以实现资源接管,需配合移动构造/赋值及std::move使用。

右值引用是C++11引入的关键特性,用&&表示,核心作用是绑定到临时对象(右值),从而支持移动语义和完美转发。它不是“更高级的引用”,而是类型系统中一种新的引用类别,让编译器能区分“可被安全搬走资源的对象”和“需要保留原样”的对象。
右值引用绑定什么?
右值引用只能绑定到**将亡值(xvalue)** 和**纯右值(prvalue)**,比如临时对象、函数返回的非引用类型、std::move()转换后的结果。不能直接绑定到具名变量(左值),除非显式转换:
-
std::string s1 = "hello";→s1是左值,std::string&& r1 = s1;错误 -
std::string&& r2 = std::string("world");正确:绑定到临时对象 -
std::string&& r3 = std::move(s1);正确:把s1“标记”为可移动状态
移动构造函数和移动赋值运算符
右值引用让类可以定义移动操作,在资源转移时避免深拷贝。典型模式是“掏空”源对象,把指针/句柄等内部资源直接接管过来,并将源置为空状态:
- 移动构造函数:
MyClass(MyClass&& other) noexcept—— 用other的成员初始化当前对象,然后设other.ptr = nullptr - 移动赋值运算符:
MyClass& operator=(MyClass&& other) noexcept—— 先释放当前资源,再交换或接管other的资源 -
noexcept强烈建议加上:容器(如std::vector)在扩容时会优先选择noexcept移动,否则可能退回到拷贝
移动语义真正生效的时机
编译器不会对所有右值自动触发移动——它依赖**重载决议**和**隐式移动规则**:
立即学习“C++免费学习笔记(深入)”;
- 函数返回局部对象时(NRVO未触发),自动视为右值,调用移动构造(如
return std::string("abc");) - 传入参数是右值引用类型,且实参是右值,匹配成功后进入移动逻辑
- 用
std::move()显式转换左值为右值引用类型,只是类型转换,不执行移动;是否真移动取决于后续是否调用了移动操作 - 容器插入、元素交换、
std::swap等标准库操作在底层大量依赖移动语义提升性能
与const左值引用的区别
别混淆const T&和T&&:const T&能绑定左值和右值(万能引用的旧称,但实际是常量左值引用),仅用于读取;T&&默认只接受右值,且允许修改源对象(因为知道它即将销毁),这是实现“搬资源”的前提。
不复杂但容易忽略









