最近在研究C++ 左值 右值,搬运、收集了一些别人的资料,供自己记录和学习,若以后看到了更好的解释,会继续补充。(打“?”是我自己不明白的地方 )
参考:《Boost程序库探秘——深度解析C++准标准库(第2版)》 9787302342731
左值:一个可以用来存储数据的变量,有实际的内存地址(变量名);
右值(非左值):“匿名”的“临时”变量,在表达式结束时生命周期终止,不能存放数据,可被修改,也可不被修改(const修饰)。
鉴别左值右值:
左值可用取地址操作符&获取地址,右值不行,会发生编译错误。
所有c++的表达式的结果不知左值就是右值(?)
++i 是左值,i++ 右值(返回的是一个临时变量,无法赋值);(?)
可以把右值得内容转移到其他的对象中去,从而完全消除了之前昂贵的拷贝代价;
T& 左值引用;
T&& 右值引用(C++11)。
c++ primer 3rd
只有在必要的时候才使用后置操作符(i++),
前置操作符返回的是左值(对象本身),而后置操作符返回的是右值。前置操作符需要的工作更少,只需加1后返回加1后的结果;而后置操作符则必须先保存原来的数值,以便返回未加1时的值,可能会花费更大的代价。
所以建议 ++i 。
MSDN
Lvalues 和 Rvalues
Visual Studio 2013 版本
每个 C++ 表达式是左值或右值。 左值是指在单个表达式的外部保留的对象。 可以将左值视为具有名称的对象。 所有变量(包括不能更改的 (const) 变量)都是左值。 左值是一个不在使用它的表达式的外部保留的临时值。 若要更好地了解左值和右值之间的区别,请考虑下面的示例:
// lvalues_and_rvalues1.cpp // compile with: /EHsc #include <iostream> using namespace std; int main() { int x = 3 + 4; cout << x << endl; }
在此示例中,x 是左值,因为它在定义它的表达式的外部保留。 表达式 3 + 4 是为一个右值,因为其计算结果为不在定义它的表达式的外部保留的临时值。
以下示例演示左值和右值的多种正确的和错误的用法:
// lvalues_and_rvalues2.cpp int main() { int i, j, *p; // Correct usage: the variable i is an lvalue. i = 7; // Incorrect usage: The left operand must be an lvalue (C2106). 7 = i; // C2106 j * 4 = 7; // C2106 // Correct usage: the dereferenced pointer is an lvalue. *p = i; const int ci = 7; // Incorrect usage: the variable is a non-modifiable lvalue (C3892). ci = 9; // C3892 // Correct usage: the conditional operator returns an lvalue. ((i < 3) ? i : j) = 7; }
说明 |
---|
此主题中的示例阐释了未重载运算符时的正确和错误用法。 通过重载运算符,可以使表达式(如 j * 4)成为左值。 |
当引用对象引用时,通常会使用术语“左值”和“右值”。 有关引用的详细信息,请参阅Lvalue 引用声明符:& 和规则引用声明符:&&。
Pasted from: <http://msdn.microsoft.com/zh-cn/library/f90831hc.aspx>
c++ primer
当一个对象被用作右值时,用的是对象的值(内容);当对象被用做左值的时候,用的是对象的身份。
原则:需要右值的地方可以用左值代替,但不能把右值当成左值(位置)来使用。
当一个左值被当成右值使用时,实际使用的是它的内容。