左值引用和右值引用

关于C++中左值引用和右值引用的一个总结

表示

& 表示左值引用

&& 表示右值引用

左值和右值

C语言中的左值和右值简单的区分就是:左值可以位于复制语句的左侧,右值不能。C++中的左值右值概念也是从此引申而来,不过有了一些更复杂的情形。

比如:

  • 以常量对象为代表的一些左值实际无法作为赋值语句的左侧运算对象
  • 某些表达式的求值结果为对象,但是却是右值而非左值

我们可以简单归纳为当一个对象被用作右值时,用的是对象的值(内容),被用作左值时,用的是对象的身份(内存中的位置)

左值引用

不能绑定到要求转换的表达式、字面常量或者返回右值的表达式

一般无法将一个左值引用绑定到一个右值上

但我们可以使用一个const左值引用绑定到一个右值上。

返回左值引用的函数,连同赋值、下标、解引用和前置递增递减运算符,都是返回左值的表达式的例子,可以使用左值引用绑定到这些表达式的结果上。

右值引用

可以绑定到要求转换的表达式、字面常量或者返回右值的表达式

但是无法将一个右值引用直接绑定到一个左值上。

返回非左值引用类型的函数,连同算数、关系、位以及后置递增递减运算符,都生成右值。我们可以使用const的左值引用或者右值引用绑定到这类表达式。

性质

左值持久;右值短暂

左值有持久的状态,右值要么是字面常量,要么是表达式求值过程中创建的临时对象

右值引用两个特性

  • 所引用的对象将要被销毁
  • 该对象没有其他用户

所以使用右值引用,可以自由接管所引用的对象的资源。

变量与std::move函数

变量表达式都是左值表达式,因此无法使用右值引用绑定到一个变量上,包括一个右值引用类型的变量上。

但是我们可以显示的将一个左值转换为对应的右值引用类型,也可以通过C++11 标准下的std:move函数来获得绑定到左值上的右值引用。该函数在utility头文件中。

std::move函数的作用是告诉编译器,我们希望像使用一个右值一样使用一个左值。当使用该函数时,就意味着我们的程序除了对这个左值赋值或销毁之外,不再使用它。也就是说调用之后,我们不能对移后源对象的值作任何假设。

也就是说我们可以销毁一个移后源对象,也可以赋予新值,但不能使用它的值。