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格式,活动内存碎片整理,内存使 ...
随机推荐
- mybatis-plus代码生成,实体类不生成父类属性
一.参考文档: 官方文档其实说的很清楚了,可能有个别地方有点不太清楚. mybatis-plus官方: https://mp.baomidou.com/guide/generator.html 模版引 ...
- 【洛谷 P2051】 [AHOI2009]中国象棋(DP)
题目链接 首先想到状压dp,但是\(n,m\)高达100,怎么压? 容易发现,每行每列最多两个象棋,否则就直接gg了. 一个巧妙的设置状态的方式是,只需要记录到当前行有多少列是放了1个炮和2个炮. 然 ...
- vue 全局挂载组件
<!-- plugin.js --> import someComponent from './components/someComponent' export default { ins ...
- 5.href和src区别? title和alt【CSS】
1.href (Hypertext Reference)指定网络资源的位置(超文本引用),从而在当前元素或者当前文档和由当前属性定义的需要的锚点或资源之间定义一个链接或者关系,在 link和a 等元素 ...
- vs2017开启JavaScript智能提示
[工具]--[选项]--[文本编辑器]--[JavaScript]--[语言服务] 把第一个钩去掉即可,如果不需要提示就打上勾
- 导航条按钮的设置UIBarButtonItem
1.目的 2.代码 // 设置导航栏的按钮 UIButton *leftNavBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 35, 35 ...
- 主流WEB服务器大对比(Apache,Nginx,Lighttpd)
一.软件介绍(apache lighttpd nginx) 1. lighttpd Lighttpd 是一个具有非常低的内存开销, cpu 占用率低,效能好,以及丰富的模块等特点. lightt ...
- git学习记录--标签随笔
创建标签: 命令git tag <name>用于新建一个标签,默认为HEAD,也可以指定一个commit id: git tag -a <tagname> -m "b ...
- (备忘)解决用Xftp向CentOS7 传文件速度慢的问题
问题原因:之前用XFTP上传文件的时候一直挺好的,今天突然速度特别慢,上传了一个多小时也没把一个一百兆的文件成功上传 查询过程: 1.网络原因:网络的确有点卡,但不至于这么慢吧,几K的速度,鉴于网络问 ...
- openwrt使用3G拔号的实践笔记
参照文档: https://soha.moe/post/make-4g-wifi-ap-with-openwrt.html 步骤: 1.安装必要的包: opkg update opkg install ...