C++ 左值(lvalue)、右值(rvalue)与右值引用(rvalue reference)

理解 C++ 中的左值、右值及其引用形式,是掌握现代 C++(尤其是 C++11 以后的移动语义/move和完美转发/perfect forwarding)必不可少的基础。

📌 什么是左值(lvalue)

左值指的是有名字、可寻址的对象,通常可以出现在赋值语句的左侧。

1

2

3

int x = 10;

x = 20; // x 是左值

int* p = &x; // 可以取地址

int x = 10;

x = 20; // x 是左值

int* p = &x; // 可以取地址

📌 什么是右值(rvalue)

右值是临时对象,不能被取地址,通常是表达式的结果或字面值常量。

1

2

3

int x = 10;

int y = x + 5; // x + 5 是右值

y = 100; // 100 是右值

int x = 10;

int y = x + 5; // x + 5 是右值

y = 100; // 100 是右值

右值不能出现在赋值语句左侧,且生命周期通常较短。

📌 右值引用(rvalue reference)

C++ 11 引入了右值引用(通过 && 语法),允许我们“捕获”右值。这为移动语义提供了基础。

1

2

3

4

5

6

7

8

void process(int& x); // 左值引用

void process(int&& x); // 右值引用

int main() {

int a = 42;

process(a); // 调用 int&

process(10); // 调用 int&&

}

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 与移动语义

1

2

std::string a = "hello";

std::string b = std::move(a); // a 被“移”给了 b

std::string a = "hello";

std::string b = std::move(a); // a 被“移”给了 b

std::move 并不移动对象,它只是把左值强制转换为右值,从而触发移动构造函数或移动赋值运算符。

💡 使用建议

使用左值引用(&):

当你需要访问和修改已有变量

不涉及资源转移

使用右值引用(&&):

希望接管临时对象的资源

编写移动构造函数或移动赋值

优化性能,避免深拷贝

总结

左值和右值是 C++ 表达式语义的核心。右值引用是现代 C++ 的重要特性,能显著提高资源管理和性能表现。理解它们的区别和用法,是成为高阶 C++ 程序员的基础。

C/C++编程

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

GD Star Ratingloading... 本文一共 541 个汉字, 你数一下对不对.