左值右值
在C++中,对值的分类非常重要,因为它决定了你可以对这些值做什么操作。左值(lvalue)和右值(rvalue)是C++中的两种主要的表达式类别,而左值引用和右值引用则是与之对应的引用类型。
左值 (Lvalue)
左值是指那些表达式,它们指向内存中的一个固定位置,这样的表达式可以出现在赋值语句的左侧。它们通常是一个变量、数组的一个元素或者一个对象的一个属性。左值可以取地址,即可以使用&
运算符来得到其内存地址。
示例:
1 | int x = 10; // x是一个左值 |
在这个例子中,x
是一个左值,因为你可以对它赋值。x
具有一个持久的内存地址,可以在程序的多个地方引用和修改。
右值 (Rvalue)
右值是指那些不指向内存中固定位置的表达式。右值通常是临时的,不能取地址,也不能在赋值语句的左侧出现。一个典型的右值是字面量或者一个表达式的结果(例如函数返回的临时对象或者一个算术表达式的结果)。
示例:
1 | int y = 10 + 5; // 10 + 5是一个右值 |
这里的表达式10 + 5
就是一个右值,因为它不对应内存中的一个固定位置,而是一个临时计算的结果,它的值可以用来初始化变量y
。
左值引用 (Lvalue Reference)
左值引用是对左值的引用。在声明中,左值引用由类型后跟一个&
符号表示。左值引用可以用来创建一个对象的别名。
示例:
1 | int a = 42; |
这里的ref
是a
的左值引用,改变ref
的值也会改变a
的值。
右值引用 (Rvalue Reference)
右值引用是C++11中引入的一种新类型引用,它允许引用右值。在声明中,右值引用由类型后跟一个&&
符号表示。右值引用使得可以安全地“移动”资源,而不是复制资源,这是C++11中引入移动语义和完美转发的关键部分。
示例:
1 | int&& rref = 10 + 5; // rref是对临时右值的引用 |
这里的rref
是一个右值引用,它引用了10 + 5
这个右值表达式的结果。
总结:
- 左值:可以在赋值语句的左侧,有持续的状态,可以取地址。
- 右值:临时的,通常不能取地址,不能在赋值语句的左侧。
- 左值引用:对左值的引用,用
&
表示。 - 右值引用:对右值的引用,用
&&
表示,C++11中新增。