c++的表达式
首先介绍下c++的表达式是什么?看下cppreference
是怎么说的。
An expression is a sequence of operators and their operands, that specifies a computation.
也就是说,在C++中,表达式(Expression)是由操作数(Operands)和运算符(Operators)组成的序列。
左值和右值就是c++中表达式的两种分类。
左值
简单理解,能够取地址的对象是左值,非临时对象的就是左值。
int a = 5; // a就可以理解成是一个左值,5就可以理解为是一个右值
"hello world"; // 字符串常量值是个左值;字符串常量会申请内存空间,同样的字符串常量使用的是同一块内存;
Object &&obj = std::move(); // 右值引用本身也是个左值,他就是个变量其实,所以也有地址;
右值
c++11之前左值和右值的说法,c++11之后有了细分,又出现了纯右值和将亡值。c++11之前的右值就可以理解为c++11之后的纯右值,这里就直接说纯右值和将亡值了。
纯右值
- 纯粹的字面值,如
11
,false
等; - 求值结果相当于字面值/一个临时对象。
- 注1:字符串字面值是左值,它是可以进行取地址的操作;
std::cout << &("hello world") << std::endl;
输出的结果是0x100a2df44
。
- 注2:++i 是左值,i++是右值
++i 和 i++类似于下面的代码,func1()返回的是一个临时对象;func2()返回的还是 i,用以区分左值还是右值。
// i++
int func1(int &i) {
int tmp = i;
i = i + 1;
return tmp;
}
// ++i
int func2(int &i) {
i = i + 1;
return i;
}
将亡值
c++11 之前的右值和 c++11 的纯右值是等价的。
c++11 提出的将亡值是随右值引用引入的,将亡值和右值引用息息相关,将亡值可以按照字面意思来理解,就是快要“死亡”的值。
将亡值表达式:
- 返回右值引用的函数调用表达式;例如
get_value()
返回一个非引用类型的对象; - 转换(cast)为右值引用的转换函数表达式。
何为“将亡”?
c++11 中,
- 用左值初始化一个对象/为一个已有对象赋值,会调用拷贝构造函数/拷贝赋值运算符,进行资源拷贝;
- 用右值来初始化/赋值时,会调用移动构造函数/移动赋值运算符来移动资源,避免资源拷贝。
当该右值完成初始化/赋值操作后,它的资源已经被移走了,同时该右值会马上被销毁,这就是“将亡”。
std::move()
和static_cast<X&&>()
将左值转为右值,这里就涉及到了将亡值,转换为右值之后原值就被销毁掉了。