C++ 左值(lvalue)、右值(rvalue)与右值引用(rvalue reference)
理解 C++ 中的左值、右值及其引用形式,是掌握现代 C++(尤其是 C++11 以后的移动语义/move和完美转发/perfect forwarding)必不可少的基础。
📌 什么是左值(lvalue)
左值指的是有名字、可寻址的对象,通常可以出现在赋值语句的左侧。
int x = 10;
x = 20; // x 是左值
int* p = &x; // 可以取地址
📌 什么是右值(rvalue)
右值是临时对象,不能被取地址,通常是表达式的结果或字面值常量。
int x = 10;
int y = x + 5; // x + 5 是右值
y = 100; // 100 是右值
右值不能出现在赋值语句左侧,且生命周期通常较短。
📌 右值引用(rvalue reference)
C++ 11 引入了右值引用(通过 && 语法),允许我们“捕获”右值。这为移动语义提供了基础。
void process(int& x); // 左值引用
void process(int&& x); // 右值引用
int main() {
int a = 42;
process(a); // 调用 int&
process(10); // 调用 int&&
}
右值引用通常与移动构造函数、移动赋值运算符、std::move 和完美转发/forwarding一起使用。
📊 左值 vs 右值 比较
| 特性 | 左值(lvalue) | 右值(rvalue) |
|---|---|---|
| 是否有名称 | 有 | 通常没有 |
| 是否可取地址 | 可以 | 不可以 |
| 是否可出现在赋值语句左侧 | 可以 | 不可以 |
| 生命周期 | 受作用域控制 | 通常是临时的 |
是否可绑定到 && |
否 | 是 |
🧪 std::move 与移动语义
std::string a = "hello";
std::string b = std::move(a); // a 被“移”给了 b
std::move 并不移动对象,它只是把左值强制转换为右值,从而触发移动构造函数或移动赋值运算符。
💡 使用建议
- 使用左值引用(
&):- 当你需要访问和修改已有变量
- 不涉及资源转移
- 使用右值引用(
&&):- 希望接管临时对象的资源
- 编写移动构造函数或移动赋值
- 优化性能,避免深拷贝
总结
左值和右值是 C++ 表达式语义的核心。右值引用是现代 C++ 的重要特性,能显著提高资源管理和性能表现。理解它们的区别和用法,是成为高阶 C++ 程序员的基础。
C/C++编程
- 理解C++中的std::transform_reduce及示例
- 使用原子 TAS 指令实现自旋锁
- C++中检测编译时与运行时: if consteval 与 std::is_constant_evaluated()
- C++ 转发引用: 完美转发的关键
- 理解 C++ 中的 dynamic_cast: 安全的向下转型与向上转型
- C与C++: restrict关键字及其在编译器优化中的作用
- C++的左值/lvalue, 右值/rvalue和右值引用/rvalue references
- C++中的assert和static_assert的区别
- C++: auto_ptr智能指针被弃用
- C++中的consteval是什么? 它与const和constexpr有何不同?
- C++ 教程: 用std::move来移动所有权
- C++中的 const和constexpr 比较
- 简易教程: C++的智能指针
- C++ 编程练习题: 如何合并两个二叉树?
- C++ 编程练习题 - 找出第三大的数
- C++ 编程练习题 - 最多连续的 1
- C++ 编程练习题 - 左子树叶节点之和 (深度优先+广度优先+递归)
- C++ 编程练习题 - 最多水容器 (递归)
- C++的异步编程: std::future, std::async 和 std::promise
- C编程练习题: 翻转整数位
- C++编程练习题: 找出字符串的所有大小小组合
- C/C++ 中的内存管理器(堆与栈)
- C++编程练习题: 对两单向链表求和
英文:C++ Lvalue, Rvalue and Rvalue References
本文一共 541 个汉字, 你数一下对不对.上一篇: C++中的assert和static_assert的区别
下一篇: 深入理解ROS中的Topics, Services和Actions(含示例)
扫描二维码,分享本文到微信朋友圈