工作生活

【记5】右值引用

2019-07-02  本文已影响0人  CozyMoonquake

今天刚好学习到右值引用的相关知识,就简单来写一下自己的理解。
右值引用是C++11中新增的一个重要特性,主要是解决旧C++标准中的两个问题:1.临时对象非必要的昂贵的拷贝操作;2.在模板函数中如何按照参数的实际类型进行转发。
新标准中的移动而非拷贝对象的能力可以大幅提升性能,而为了支持移动操作,就引入了右值引用。顾名思义,右值引用就是必须绑定到右值的引用,通过&&而不是&来获得右值引用,例子如下:

int i=10;
int &l1=i;                //正确:l1引用i
int &&r1=i;              //错误:不能将一个右值引用绑定到一个左值上
int &l2=i*10;            //错误:i*10是一个右值
const int &l3=i*10;      //正确:可以将一个const的引用绑定到一个右值上
int &&r2=i*10;           //正确:将r2绑定到乘法结果上

一般来说,一个左值表达式表示的是一个对象的身份,一个右值表达式表示的是对象的值。对于左值引用,我们不能将其绑定到要求转换的表达式、字面常量或是返回右值的表达式。而右值引用刚好相反,我们可以将一个右值引用绑定到这类表达式上,但不能将其直接绑定到一个左值上。
由上述即可知,左值有持久的状态,而右值要么是字面常量,要么是在表达式求值过程中创建的临时对象。由于右值引用只能绑定到临时对象,于是可知所引用的对象将要被销毁,且该对象没有其他用户。这两个特性意味着:使用右值引用的代码可以自由地接管所引用的对象的资源。
另外,我们不能将一个右值引用绑定到一个右值引用类型的变量上

int &&r1=10;        //正确:字面常量是右值
int &&r2=r1;        //错误:表达式r1是左值

因为右值是表示临时对象的,而变量是持久的,直到离开作用域时才被销毁。

标准库move函数
虽然不能将一个右值引用直接绑定到一个左值上,但我们可以显式地将一个左值转换为对应的右值引用类型。我们还可以通过一个名为move的新标准库函数来获得绑定到左值上的右值引用,此函数定义在头文件utility中。如下所示:

int &&r3=std::move(r1);        //正确

move调用告诉编译器:我们有一个左值,但我们希望像一个右值一样处理它。必须注意,调用move就意味着承诺:除了对r1赋值或销毁外,将不再使用它。

上一篇下一篇

猜你喜欢

热点阅读