右值引用
右值引用
- lvalue 是
loactor value
的缩写,rvalue 是read value
的缩写 - 左值是指
存储在内存中、有明确存储地址(可取地址)的数据;
- 右值是指
可以提供数据值的数据(不可取地址);
通过描述可以看出,区分左值与右值的便捷方法是:可以对表达式取地址(&)就是左值,否则为右值 。
所有有名字的变量或对象都是左值,而右值是匿名的。
int a = 520;
int b = 1314;
a = b;
一般情况下,位于 =
前的表达式为左值,位于 =
后边的表达式为右值。也就是说例子中的 a, b
为左值,520,1314
为右值。a=b
是一种特殊情况,在这个表达式中 a, b
都是左值,因为变量 b
是可以被取地址的,不能视为右值。
C++11 中右值可以分为两种:一个是将亡值( xvalue, expiring value)
,另一个则是纯右值( prvalue, PureRvalue)
:
纯右值:
非引用返回的临时变量、运算表达式产生的临时变量、原始字面量和 lambda 表达式等将亡值:
与右值引用相关的表达式,比如,T&& 类型函数的返回值、 std::move 的返回值等。
int main(){
//左值
int num = 9;
//左值引用
int& a = num;
//右值
//右值引用
int&& b = 8;
//常量左值引用
const int& c = num;
const int& c = b;//可以用右值引用初始化左值引用,也可以使用常量右值引用给常量左值引用初始化
//常量右值引用
const int&& d = 6;
const int&& e = b;//error,右值引用只能够通过右值初始化
int&& f = b;//error
}
右值引用
右值引用就是对一个右值进行引用的类型,因为右值是匿名的,所以我们只能通过引用的方式找到它.无论声明左值引用还是右值引用都必须立即进行初始化,因为引用类型本身并不拥有所绑定对象的内存,只是该对象的一个别名。通过右值引用的声明,该右值又“重获新生”
其生命周期与右值引用类型变量的生命周期一样,只要该变量还活着,该右值临时量将会一直存活下去。
左值 右值 将亡值
比如move(X), 移动构造函数class_name(class_name &&X)中的X都是将亡值
对于形如这样的赋值class_name t = getObj()
,其中getObj()返回一个临时对象,如果class_name有移动构造,那么就会调用移动构造函数,否则调用拷贝构造函数
移动构造
拷贝构造函数就是为了防止浅拷贝