C++2.0新特性(五)——<Rvalue_reference和move语义>
一、Rvalue_reference(右值引用)和move语义
1、左右值概念区分
左值:表达式结束后依然存在的对象,我们也叫做变量;
右值:表达式结束后就不存在的临时对象。
2、判断左值和右值
能对表达式取地址的是左值,否则就是右值
左值指的是既能够出现在等号左边也能出现在等号右边的变量(或表达式),右值指的则是只能出现在等号右边的变量(或表达式)。
3、move语义
右值引用出现再c++03版本之后,它可以避免一些不必要的拷贝和临时对象,当赋值操作的右边是一个右值时,左值可以偷取右值里的资源,而不必去执行allocator(分配内存的动作),这就是move语义。
4、左右值举例分析
- 左右值书写分析

注意:虽然string和复数的举例推翻了左右值书写的准则,但是这是由于一些c++定义类型导致的,我们不要去管他,我们只要记住两点:1、临时对象就是一个右值;2、右值不要出现在等号左边。
5、右值引用
在c++11之前我们对一个函数返回值取地址是错误的,但是在新语法中,我们可以使用&&符号表示对右值取引用或者使用move函数将一个左值变为右值,相应的,我们也要为对应的元素对象实现一个move构造函数或者move赋值函数的重载版本(适用容器中操作元素时)。比如在做容器的在c++ 2.0之后,容器的插入动作都提供了一个insert的重载版本,专门适用这种新语法,如下所示:

当编译器检测到我们insert的值是一个右值(move函数返回一个右值)或者右值引用(&&,临时对象都会被当成右值引用)时,会调用下面新增的这个重载函数,让它偷取这个右值的东西免去自身取构造内存的动作,因为插入动作会调用拷贝构造函数,如果插入的元素是一个基本类型而不需要额外提供什么,但是如果插入的是一个复杂类型,原本我们需要写一个拷贝构造函数,开辟一块内存一个个的赋值过去,但现在我们要提供一个move搬移构造就行了(比如像string(编译器已经实现)类,move构造函数只是将既有的内部字符数组赋予新对象就行了,此时相当于新对象指针和原对象指针指向同一个地方,要注意执行move后原对象的指针是个不确定状态,不能使用),所以任何非平凡的类(除了基本类型),都应该提供move构造和move assignment(赋值)函数:


- 这里说一下move中的偷的概念,所谓偷就是借用之前的值,对于指针来说就是两个指针指向同一个地方,也就是说move语义就是指针的浅拷贝,为了指针的安全我们还要在偷完之后将原来的指针打断以禁止后续再使用这个值;
- 右值经函数转交到下一个函数时会变成一个左值。

6、右值引用使用准则:
使用右值的函数也不能返回局部变量


7、move类举例
- move构造函数对接的是拷贝构造函数,下面将两个做对比,move做浅拷贝后,要将原来指针赋空(记住一定要将原来的指针赋空打断,因为容器在做插入操作时产生的临时对象生命周期结束后会调用析构函数释放指针内存,如果原来的指针没有赋空析构后容器里面已插入的指针就是悬空指针,引起崩溃,而前面指针赋空断开则不会有影响(对一个空指针delete操作相当于什么都不做))

- 拷贝赋值对接move拷贝赋值函数

8、有无move版本对容器的影响
- Vector 插入元素时影响很大
- 除vector以外的其他容器插入元素时影响都不大
- deque的极端情况,比如每次都在buffer中间插入,会产生很多的拷贝动作,影响也大
C++2.0新特性(五)——<Rvalue_reference和move语义>的更多相关文章
- [转]Servlet 3.0 新特性详解
原文地址:http://blog.csdn.net/xiazdong/article/details/7208316 Servlet 3.0 新特性概览 1.Servlet.Filter.Listen ...
- iOS开发——新特性OC篇&Swift 2.0新特性
Swift 2.0新特性 转眼间,Swift已经一岁多了,这门新鲜.语法时尚.类型安全.执行速度更快的语言已经渐渐的深入广大开发者的心.我同样也是非常喜爱这门新的编程语言. 今年6月,一年一度 ...
- [C#]6.0新特性浅谈
原文:[C#]6.0新特性浅谈 C#6.0出来也有很长一段时间了,虽然新的特性和语法趋于稳定,但是对于大多数程序猿来说,想在工作中用上C#6.0估计还得等上不短的一段时间.所以现在再来聊一聊新版本带来 ...
- webpack 4.0.0-beta.0 新特性介绍
webpack 可以看做是模块打包机.它做的事情是:分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式 ...
- Day07 jdk5.0新特性&Junit&反射
day07总结 今日内容 MyEclipse安装与使用 JUnit使用 泛型 1.5新特性 自动装箱拆箱 增强for 静态导入 可变参数方法 枚举 反射 MyEclipse安装与使用(yes) 安装M ...
- 四、C# 5.0 新特性——Async和Await使异步编程更简单
一.引言 .NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两个关键字简化了异步编程,之所以简化了,还是因为编译器给我们做了更多的工作,下面就 ...
- [翻译] C# 8.0 新特性 Redis基本使用及百亿数据量中的使用技巧分享(附视频地址及观看指南) 【由浅至深】redis 实现发布订阅的几种方式 .NET Core开发者的福音之玩转Redis的又一傻瓜式神器推荐
[翻译] C# 8.0 新特性 2018-11-13 17:04 by Rwing, 1179 阅读, 24 评论, 收藏, 编辑 原文: Building C# 8.0[译注:原文主标题如此,但内容 ...
- android6.0、7.0、8.0新特性总结之开发应用时加以考虑的一些主要变更。
android6.0 参考一:简书Android 6.0 新特性详解 参考二:关于Android6.0以上系统的权限问题 参考三:值得你关注的Android6.0上的重要变化(一) 参考四:值得你关注 ...
- Redis4.0新特性
redis 4.0 新特性 Redis 4.0在2017年7月发布为GA.包含几个重大改进:更好的复制(PSYNC2),线程DEL / FLUSH,混合RDB + AOF格式,活动内存碎片整理,内存使 ...
随机推荐
- Asp.Net Core File的操作
FileOption 内置类(通过服务注入) 该操作类的功能是实现对文件的删除,修改查询功能,该类基本完成了对文件的操作,同样是用最简单的代码实现了文件操作功能.
- Python学习文档指引
Python文档资源: 形式 角色 #注释 文件中的文档 dir函数 对象中可用属性的列表 文档字符串:__doc__ 附加在对象上的文件中的文档 PyDoc:help函数 对象的交互帮助 PyDoc ...
- 交易开拓者旗舰版(TB旗舰版)软件升级中如何迁移用户数据
方法一: 1.导出工作区,桌面和系统设置.操作:文件->导入和导出 2.导出公式.操作:tb公式->公式导入导出. 3.拷贝工作室文件.目录在:user\tb用户名\Workroom 4. ...
- 2.kafka 分布式集群安装
Kafka集群安装主节点h201,从节点h202.h2031.安装jdk1.8[hadoop@h201 ~]$ /usr/jdk1.8.0_144/bin/java -version 2.安装zook ...
- xadmin 配置内置User模型
xadmin 配置内置USER模型 默认展示 在你的User模型对应的app下创建adminx 文件 import xadmin from django.contrib.auth import get ...
- 数据库PDO简介
php简介,php历史,php后端工程师职业前景,php技术方向,php后端工程师职业体系介绍. php是世界上使用最广泛的web开发语言,是超文本预处理器,是一种通用的开源脚本语言,语法吸收了c语言 ...
- cmd xcopy进行远程复制
首先 win+R 打开cmd 1 目标远程服务器 查看共享的文件夹 net share 2 与远程建立连接 net use \\192.168.3.200\ipc$ Yhxwl123456 /us ...
- APS实现的要点与难点
在前一篇关于文章中讨论了不同层级.粒度的生产计划,在各行业中受重视程度的差异问题. 承蒙大家热烈讨论.本文则在收集各方高见的基础上,对于供应链上各个环节的运营.生产计划再作稍微深入一点的探讨.本文将列 ...
- java基础(10)---leetcode的String、数组以及集合的一些使用
整数 一.整数反转_7 /* 12345 变成 54321 */ public class 整数反转_7 { public static void main(String[] args){ int x ...
- formset的简单使用
1.modelform class StudentStudyRecordModelForm(forms.ModelForm): class Meta: model = StudentStudyReco ...