C++右值引用,左值(lvalue)、将亡值(xvalue)、纯右值(prvalue)

右值引用

C++11增加了移动特性(把资源所有权交出给新对象),基于两个原因:

  1. 在很多时候,对象拷贝后就立即被销毁了,此时移动而非拷贝对象会大幅度提升性能。
  2. 一些类(比如IO类、unique_ptr)包含不能被共享的资源(IO缓冲、指针),所以这些类型的对象不能被拷贝,但可以被移动。

因此引出新的引用类型——右值引用:必须绑定到右值的引用。我们通过 &&来获得右值引用。
右值引用有一个重要性质——只能绑定到一个将要摧毁的对象。因此可以自由地将一个右值引用资源移动到另一个对象。


C++03标准中的左值与右值

C++03标准中将表达式分为左值和右值,并且“非左即右”:

左值指既能够出现在赋值符号左边,也能出现在赋值符号右边的变量;右值则是只能出现在赋值符号右边的值。

区分一个表达式是左值还是右值,最简便的方法就是看能不能够对它取地址:如果能,就是左值;否则,就是右值。

能标识一个对象的表达式 或 函数 的表达式就是左值表达式。


C++11标准中的表达式分类

右值引用的引入,使得C++11标准中对表达式的分类不再是非左值即右值那么简单。

基本值类型与表达式的两个属性相对应:

  1. 有"身份"[has identity]:能够确定某个表达式是否和另一个表达式指涉[refers to]同一个实体,例如,通过比较它们标识[identify]出来的函数或者对象的地址(直接或间接得到的)。
  2. 能被移动[can be moved from]:能够被移动构造函数、移动赋值操作符或者其它实现[implement]移动语义[move semantics]的重载函数绑定[bind to]。

根据上面两个属性,我们可以对表达式进行分类:

  1. 有"身份"但是不能"被移动"的表达式被称为左值表达式[lvalue expression];
  2. 有"身份"同时能"被移动"的表达式被称为 xvalue 表达式[xvalue expression];
  3. 没有"身份"但是能"被移动"的表达式被称为纯右值表达式[prvalue expression];
  4. C++没有既没有"身份"也不能"被移动"的表达式;

每个C++表达式只属于三种基本值类别中的一种:左值 (lvalue)、纯右值 (prvalue)、将亡值 (xvalue)

C++11标准中对表达式的分类,简单解释如下:

  • lvalue(左值)仍然是传统意义上的左值;
  • xvalue(eXpiring value)字面意思可理解为生命周期即将结束的值(将亡值),它是某些涉及到右值引用的表达式的值,例如:调用一个返回类型为右值引用的函数的返回值就是xvalue。详细介绍在下面。
  • prvalue(pure rvalue)字面意思可理解为纯右值,传统意义上的右值,例如临时对象字面值常量(字符串字面值除外)等。
  • glvalue(generalized value)广义的左值(泛左值),表明其有身份(has identity),包括传统的左值和xvalue。
  • rvalue除了传统意义上的右值,还包括xvalue。

依据是否可以移动,值类别可以分为:

  • 左值(lvalue) :指向内存位置的表达式被称为左值(lvalue)表达式,表示对象的身份,可以取地址,不可移动。
  • 右值(rvalue) :右值是不能对其进行赋值的表达式,表示的是对象的值,不可取地址,包含了 将亡值、纯右值(可被右值引用类型匹配),可移动。

在这里插入图片描述

将亡值

xvalue(expiring value)将亡值
通常指代一个生存周期即将结束的值(因此其资源可以被转移)。是某些涉及到右值引用的表达式的值,根据C++11标准,以下四种情况属于xvalue:

  • 调用函数(无论是隐式还是显式)的结果,该函数的返回类型是对对象类型的右值引用,
  • 对对象类型的右值引用的强制转换,
  • 类成员访问表达式,指定非引用类型的非静态数据成员,其中对象表达式是xvalue,或
  • 指向成员表达式的*指针,其中第一个操作数是xvalue,第二个操作数是指向数据成员的指针。

一般来说,具名的右值引用(named rvalue reference)属于左值,不具名的右值引用(unamed rvalue reference)就属于xvalue,而对函数的右值引用不论是否具名都当做左值处理。
举例:

struct A {
	int m;
};
A&& operator+(A, A);
A&& f();
A a;
A&& ar = static_cast<A&&>(a);

f()、f().m、static_cast<A&&>(a)、a+a都是将亡值xvalue,ar是左值。



参考:
https://blog.csdn.net/loveyumomo/article/details/23214341
https://www.cnblogs.com/zpcdbky/p/5275959.html
https://www.cnblogs.com/KillerAery/p/12802771.html
https://blog.csdn.net/yanglingwell/article/details/51173063

  • 13
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值