总结--C++ primer 5
一、左值和右值(P121)
1. 概念
C++的表达式,要不然是右值,要不然是左值。
这两个名词继承与C语言,在C中是为了帮助记忆:左值可以位于赋值语句的左侧,右值则不能。在C++中,二者的区别没那么简单:当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。
一个重要的原则(P470有一个例外):在需要右值的地方可以用左值来代替,但是不能把右值当成左值(也就是位置)使用。当一个左值被当成右值使用时,实际使用的是它的内容(值)。
要用到左值的运算符:
1. 赋值运算符需要一个(非常量)左值作为其左侧运算对象,得到的结果也仍然是一个左值。
2. 取地址符(&)作用于一个左值运算对象,返回一个指向该运算对象的指针,这个指针是一个右值。
3. 返回左值引用的函数、内置解引用运算符、下标运算符、迭代器解引用运算符、string和vector的下标运算符的求值结果都是左值。
4. 内置类型和迭代器的递增递减运算符作用于左值运算对象,其前置版本所得结果也是左值。
2. 左值持久;右值短暂
左值有持久的状态,而右值要么是字面常量,要么是在表达式求值过程中创建的临时对象。
二、右值引用(P470)
1. 概念
为了支持移动操作,新标准引入一种新的引用类型--右值引用。所谓右值引用就是必须绑定到右值的引用。
重要性质:右值引用只能绑定到一个将要销毁的对象(字面常量/临时对象)。
由于右值引用只能绑定到临时对象,得:
1. 所引用的对象将要被销毁
2. 该对象没有其他用户
返回右值的表达式,包括:返回非引用类型的函数及算术、关系、位和后置递增/递减运算符。
2. 应用
对于左值引用,不能将其绑定到要求转换的表达式、字面值常量或是返回右值的表达式。而右值引用可以绑定到这类表达式,但不能将一个右值引用直接绑定到一个左值上。
返回非引用类型的函数,连同算术、关系、位以及后置递增/递减运算符,都生成右值。我们不能将一个左值引用绑定到这类表达式上,但可以将一个const的左值引用或者一个右值引用绑定到这类表达式。
1 int i=42; //i是一个变量,变量是左值 2 int &r=i; //正确:r引用i 3 int &&rr=i; //错误:不能将一个右值引用绑定到一个左值上 4 int &r2=i*42; //错误:i*42是右值 5 const int &r3=i*42; //正确:可以将一个const 左值引用绑定到一个右值上 6 int &&rr2=i*42; //正确:将rr2绑定到乘法结果上
3. 变量是左值
变量可以看做只有一个运算对象而没有运算符的表达式。变量表达式都是左值。则:不能将一个右值引用绑定到一个右值引用类型的变量上。
int &&rr1=42; //字面常量是右值 int &&rr2=rr1; //错误:表达式rr1是左值
变量是持久的,直至离开作用域时才被销毁。