C++Review12_左值、右值、引用、右值引用和移动语义

摘要:
在C++11中,右值引用就是对一个右值进行引用的类型。左值引用是具名变量值的别名,而右值引用则是不具名(匿名)变量的别名。在C++11的程序中,所有的值必属于左值、将亡值、纯右值三者之一。==============================================右值引用的作用:C++11中引入的右值引用正好可用于标识一个非常量右值。C++11中用&表示左值引用,用&&表示右值引用;右值引用根据其修饰符的不同,也可以分为非常量右值引用和常量右值引用。

简单来说,再赋值符号“=”左边的就是左值;右边的就是右值;

例如 x = y;

左值 ,编译器认为x的含义是x所代表的地址;这个地址只有编译器知道。在编译时确定;编译器在特定的区域保存这个地址;给x赋值的意思就是往x所代表的地址的内存空间中赋值;

右值,编译器认为y的含义y所代表的地址里的内容;这个内容是什么,只有运行时才知道;

=================================================

左值肯定是可修改的:意思就是出现在赋值符号左边所代表的地址上的内容一定是可以被修改的。换句话说,我们只能给非只读变量赋值。

左值一般是一个变量,可以被赋值的变量。(const变量是一个例外只能做右值)。

我的理解是可修改的变量才是左值(其实也不准确,应该是可以放在赋值符号左边;const变量也是某种意义上的左值,但是不能放在赋值符号左边;引用是变量的别名;

粗略来讲,左值是一个有地址的变量 。

对左值和右值的一个最常见的误解是:等号左边的就是左值,等号右边的就是右值。左值和右值都是针对表达式而言的,左值是指表达式结束后依然存在的持久对象,右值是指表达式结束时就不再存在的临时对象。一个区分左值与右值的便捷方法是:看能不能对表达式取地址,如果能,则为左值,否则为右值。

此外讨论数组能不能作为左值

数组是不能作为整体被修改的,所以数组不是左值;

例如一个数组 a;a是不能作为左值的,可以把a[i]作为左值。

数组是特殊的变量,只能一个个单独访问其元素,单独修改其元素。

如果a作为左值,编译器会认为a表示的是首元素的首地址。所以只能访问到a[0]。

进一步讲:

左值就是能对表达式取地址、或(可修改的具名对象/变量。一般指表达式结束后依然存在的持久对象(其实就是分配了地址)。

================================================

右值是右侧表达式所代表的内容。

右值是表达式的值(不是引用),可以放在赋值右面。

右值对于编译器来说,并没有分配一块内存来保存其地址,就是不能被寻址。是一个临时的对象;

他可以是不占据内存空间的临时量或字面量,可以是不具有写入权的空间实体。

================================================

通常讨论的引用都是指左值引用。

左值引用还可以划分为:

常量左值引用 (是一个万能引用类型):可以绑定到常量左值、常量右值、非常量右值、非常量左值;

非常量左值引用:只能绑定到非常量左值;绑定到其他类型会导致很多问题,例如违反了常量的规定,以及使用一个被销毁的临时对象(非常量右值);

================================================

右值引用: //摘抄下方链接

在C++11中,右值是由两个概念构成的,一个是将亡值(xvalue,eXpiring Value),另一个则是纯右值(prvalue,Pure Rvalue)

纯右值不能取地址,一些运算表达式,比如1 + 3产生的临时变量值,也是纯右值。而不跟对象关联的字面量值,比如:2、‘c’、true,也是纯右值。此外,类型转换函数的返回值、lambda表达式等都是纯右值。

在C++11中,右值引用就是对一个右值进行引用的类型。事实上,由于右值通常不具有名字,我们也只能通过引用的方式找到它的存在。通常情况下,我们只能是从右值表达式获得其引用。比如:
T && a = ReturnRvalue();

这个表达式中,假设ReturnRvalue返回一个右值,我们就声明了一个名为a的右值引用,其值等于ReturnRvalue函数返回的临时变量的值。

在上面的例子中,ReturnRvalue函数返回的右值在表达式语句结束后,其生命也就终结了(通常我们也称其具有表达式生命期),而通过右值引 用的声明,该右值又“重获新生”,其生命期将与右值引用类型变量a的生命期一样。只要a还“活着”,该右值临时量将会一直“存活”下去。

将亡值则是C++11新增的跟右值引用相关的表达式,这样表达式通常是将要被移动的对象(移为他用),比如返回右值引用T&&的 函数返回值、std::move的返回值(稍后解释),或者转换为T&&的类型转换函数的返回值(稍后解释)。

右值引用和左值引用都是属于引用类型。无论是声明一个左值引用还是右值引用,都必须立即进行初始化。而其原因可以理解为是引用类型本身自己并不拥有所绑定对象的内存,只是该对象的一个别名。左值引用是具名变量值的别名,而右值引用则是不具名(匿名)变量的别名

在C++11的程序中,所有的值必属于左值、将亡值、纯右值三者之一。

==============================================

右值引用的作用:

C++ 11中引入的右值引用正好可用于标识一个非常量右值。C++ 11中用&表示左值引用,用&&表示右值引用;

右值引用根据其修饰符的不同,也可以分为非常量右值引用和常量右值引用。

非常量右值引用只能绑定到非常量右值,不能绑定到非常量左值、常量左值和常量右值;如果允许绑定到非常量左值,则可能会错误地窃取一个持久对象的数据, 而这是非常危险的;如果允许绑定到常量左值和常量右值,则非常量右值引用可以用于修改常量左值和常量右值,这明显违反了其常量的含义。

常量右值引用可以绑定到非常量右值和常量右值,不能绑定到非常量左值和常量左值(理由同上)。

为了支持移动操作(包括移动构造函数和移动赋值函数),C++才引入了一种新的引用类型——右值引用,可以自由接管右值引用的对象内容。

右值引用的使用:https://www.cnblogs.com/likaiming/p/9045642.html

================================================

移动语义:

C++11的移动语义:https://www.cnblogs.com/sunchaothu/p/11392116.html

我理解的右值引用、移动语义和完美转发:https://www.jianshu.com/p/d19fc8447eaa

================================================

相关链接:

左值,右值,右值引用:https://www.cnblogs.com/wuchanming/p/3735907.html //这个链接讲得很好

C++的引用类型的变量到底占不占用内存空间?:https://www.cnblogs.com/karottc/p/cpp-reference.html

C++右值引用:https://www.cnblogs.com/wuchanming/p/3735879.html

免责声明:文章转载自《C++Review12_左值、右值、引用、右值引用和移动语义》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇在ASP.NET 2.0中使用样式、主题和皮肤Linq对DataTable数据的分组统计下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

SQL 存储过程入门(变量)

SQL 存储过程入门(变量)(二)上一篇我们讲到了SQL存储过程的基本定义,怎么创建,使用,这篇就来讲一下变量的使用。 变量分文局部变量和全局变量 局部变量是@开头,全局变量是@@开头,这里我们主要讲局部变量,全局变量我们后面再讲。 在c# 语言中,定义一个变量很简单,例如 int i=0; --定义加赋值。 在sql中,定义一个变量需要关键字DECLAR...

iOS开发中 类、对象、实例变量、成员变量、属性变量等区别和关系

类(class):具有相同属性和行为等同一类元素等总称,类是一个抽象的概念。 区分是类还是对象,看它能否继续被细分。 在OC中,类是表示对象类型的结构体,对象通过类来获取自身的各种信息。类由两个部分组成:*.h和*.m文件组成。 *.m文件中 implemention部分是类的实现部分,内部包含类中的各种信息,包括各种实例方法或类方法。 类别( categ...

阿里巴巴Java开发手册(命名规范/常量定义篇)——查自己的漏-补自己的缺

一、编程规约 (一) 命名规约 1. 【强制】所有编程相关命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。 反例: _name / __name / $Object / name_ / name$ / Object$ 6. 【强制】抽象类命名使用Abstract或Base开头;异常类命名使用Exception结尾;测试类命名以它要测试的...

IE 浏览器各个版本 JavaScript 支持情况一览表

摘自:http://www.open-open.com/lib/view/open1387415311921.html 不同版本的 Internet Explorer 浏览器支持不同的 JavaScript 元素集。标准模式(有 <!doctype> 指令时 Internet Explorer 所有当前版本中使用的模式)支持的一组元素与突发模式...

高质量C++/C 编程指南一

首先,强烈推荐林锐博士这本《高质量C++/C 编程指南》,请花一两个小时认真阅读这本百页经书,你将会获益匪浅。草草看过,个人收获记录如下。 头文件的作用略作解释:(1)通过头文件来调用库功能。在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的库即可。用户只需要按照头文件中的接口声明来调用库功能,而不必关心接口怎么实现的。编译器会从库...

const与readonly的区别

const与readonly总结如下: 1.const和readonly在指定初始值以后将可读不可写 2.const是编译时常量,readonly是运行时常量. 因此const只能在该字段的声明中初始化,而readonly字段可以在声明或构造函数中初始化,因此根据构造函数的不同,readonly可能有不同的值 例如: const int A =...