右值引用作用是可以减少内存拷贝次数,从而优化性能。

首先,什么是右值?右值是一个与左值相区分的概念。左值是:既能出现在等号左边也能出现在等号右边的变量或表达式,比如int a = 5,那么a就是一个左值,因为它可以出现在等号左边被赋值,也可以在等号右边给别人赋值。右值:因为声明结束后会被销毁,所以不能放在等号左边,比如上面int a = 5;这句话的5,就是一个明显的右值。

我们知道复制构造函数调用的一个条件,就是函数返回值是一个类对象的时候。比如说下面的场景:

String test()
{String teststr = "this is a test";//调用拷贝构造函数return teststr;//返回的时候同样调用拷贝构造函数
}

它的返回值是一个类string的对象。在返回teststr的时候,会调用拷贝构造函数,在内存空间中再次分配一块空间存放类对象。但是这种拷贝构造是完全没有必要的,因为作为一个teststr在实际中并没有派上用场。如果堆内存很大,就可能出现额外的内存消耗,所以我们能不能想个办法避免这多余的一次拷贝呢?答案就是右值引用。右值引用避免了拷贝构造函数的调用,使得新构造出来的对象直接使用原来临时右值对象的地址空间,避免了内存空间重复复制造成的浪费。

MyString& operator=(MyString&& other)//&&为右值引用{if (*this != other){m_nLen = other.m_nLen;m_pData = other.m_pData;other.m_pData = NULL;}return *this;}

利用右值引用,相当于只进行了指针的转移,并没有真正进行复制。避免无意义的复制,使得被移走资源的右值在废弃时已经成为空壳,析构的开销也会降低。

2. 移动语义

移动语义和移动构造函数相关联,同样避免的是内存重复复制带来的性能损耗。当函数返回一个类对象时,临时对象会析构掉之前我们又重新申请与其相同内存且复制内容,而移动构造函数避免了这个过程,从而减少复制次数。复制构造函数和移动构造函数对比如下图所示:

#include <iostream>
using namespace std;class HasPtrMem
{
public:HasPtrMem()//构造函数{ cout << "Construct! "<< endl;} HasPtrMem(const HasPtrMem & h)//复制构造函数{ cout << "Copy construct! "<< endl;}HasPtrMem(HasPtrMem&& h)   // 移动构造函数{cout << "Move construct! "<< endl;}~ HasPtrMem(){ cout << "Destruct! " << endl;} };HasPtrMem GetTemp()
{ return HasPtrMem();
} int main()
{ HasPtrMem a = GetTemp();
}
/*输出:
Construct!
Move construct!
Destruct!
Destruct!
*/

我们可以发现对于一个临时对象HasPtrMem()生成之后,如果调用拷贝构造函数,那么这个a对象和HasPtrMem()实际上是不同地址的,因为这是拷贝构造函数进行的一次操作;而当有了移动构造函数之后,实际上就不会调用拷贝构造函数,而会调用移动构造函数,那么用移动构造函数生成的对象a的地址,实际上就是那个临时对象HasPtrMem()的地址,这样避免新开辟内存空间,而这个临时对象的内存,也不会因为这句话的结束而被析构掉。所以移动语义实际上和右值引用相辅相成,共同完成减少内存拷贝次数,节省堆空间,优化性能的作用。

3. move()语义:

因为右值引用是通过移动构造函数直接指向临时对象的内存空间从而达到节省内存空间的作用,而临时对象往往是右值,也就是右值引用。那么左值可不可以借鉴这个方法呢?实际上也是可以的,这就是move()函数的功能:std::move()实际上把一个左值转换成右值,从而方便使用移动语义。move()只是把左值转换成右值,不涉及到内存拷贝。

MyString str1 = "hello";
MyString str2(str1);//复制构造函数,调用MyString(const MyString &str)
MyString str3 = move(str2);//移动语义,调用MyString(MyString && str);

C++11新特性 右值引用与移动语义相关推荐

  1. C++11 标准新特性: 右值引用与转移语义(点评)

    <<C++11 标准新特性: 右值引用与转移语义>> 原文地址如下 http://www.ibm.com/developerworks/cn/aix/library/1307_ ...

  2. std::move C++11 标准新特性: 右值引用与转移语义

    新特性的目的 右值引用 (Rvalue Referene) 是 C++ 新标准 (C++11, 11 代表 2011 年 ) 中引入的新特性 , 它实现了转移语义 (Move Sementics) 和 ...

  3. C++11 标准新特性: 右值引用与转移语义

    原文地址 http://www.ibm.com/developerworks/cn/aix/library/1307_lisl_c11/ C++ 的新标准 C++11 已经发布一段时间了.本文介绍了新 ...

  4. 【转】C++11 标准新特性: 右值引用与转移语义

    VS2013出来了,对于C++来说,最大的改变莫过于对于C++11新特性的支持,在网上搜了一下C++11的介绍,发现这篇文章非常不错,分享给大家同时自己作为存档. 原文地址:http://www.ib ...

  5. C++ C++11新特性--右值引用

    左值与右值 在C语言中,左值和右值一般有两种区分的方法.可以出现在赋值符号"="的两边的值为左值,只能出现在赋值符号"="的右边的值为右值:还有一种说法是能取地 ...

  6. C++11中的右值引用及move语义编程

    C++0x中加入了右值引用,和move函数.右值引用出现之前我们只能用const引用来关联临时对象(右值)(造孽的VS可以用非const引用关联临时对象,请忽略VS),所以我们不能修临时对象的内容,右 ...

  7. C++11中的右值引用

    http://www.cnblogs.com/yanqi0124/p/4723698.html 在C++98中有左值和右值的概念,不过这两个概念对于很多程序员并不关心,因为不知道这两个概念照样可以写出 ...

  8. [C++11] 右值引用和移动语义

    c++11引入了右值引用和移动语义,通过避免无谓的复制,以提高程序的执行效率. 1.左值与右值 c++中的数值必属于左值或右值之一,通常有以下方法进行区分: 左值:在赋值语句左侧,右值:在赋值语句右侧 ...

  9. C++11特性——右值引用

      前言:C++11是继98/03版本之后的大改版,其中增加了许多新特性,得到广泛的应用.这篇文章就介绍其中的右值引用.希望能够解释明白以下三个问题:   1.什么是右值引用?   2.右值引用有什么 ...

最新文章

  1. 今日 Paper | 跨模态行人重识别;对抗时尚迁移;学会注意错误等
  2. 求两个有序数组的中位数-算法导论
  3. tomcat做成服务
  4. 谁是ASML的最大股东?为何荷兰光刻巨头要听美国的话?
  5. 怎么判断自己适不适合读博士?
  6. 有位哥们坚持不用微服务架构,被老板踢出了群聊···
  7. DataBinder.Eval数据绑定中的使用
  8. OpenShift 4 之通过ImageTrigger自动构建变化级联镜像
  9. 《黄聪:手机移动站SEO优化教程》4、如何实现手机移动网站和PC站点的自主适配...
  10. 【学习总结】Git学习-参考廖雪峰老师教程十-自定义Git
  11. java上传ftp_java实现FTP文件上传与文件下载
  12. bisect algorithm(python 的标准库函数 bisect model)
  13. 字符数组的定义与使用具体解析
  14. Linux SendMail发送邮件失败诊断案例(四)
  15. C#获取二维数组的行数和列数及其多维。。。
  16. linux 查看硬盘的uuid_ubuntu16.04 挂载新硬盘
  17. 冰雪传奇刷怪计时器_冰雪传奇BOSS计时器
  18. Linux【环境部署 02】yum源镜像下载+挂载镜像+本地yum源配置+局域网yum源服务搭建+局域网yum源使用(一篇学会离线yum源配置)
  19. 苹果旧版app_苹果手机教你安装旧版app
  20. LiveQing流媒体RTMP推流服务-如何获直播流地址 HLS/HTTP-FLV/WS-FLV/WebRTC/RTMP视频流地址

热门文章

  1. python工资高还是java-未来Java、大数据、Python哪个前景更好,薪资更高?
  2. python练手经典100例-10 个最值得 Python 新人练手的有趣项目
  3. python可以自学编程吗-Python入门学习难吗,新手如何学习
  4. python基础30个常用代码-30个Python常用极简代码,拿走就用
  5. python计算工资编程-老男孩学Python编程后薪资待遇高吗?
  6. 语音识别 | 从入门到精通的高效选择!
  7. 数值分析共轭梯度法matlab程序,数值分析11(共轭梯度法).ppt
  8. 本地apk安装是什么意思_Sony电视安装第三方播放器
  9. MySQL 8.0安装记录
  10. java math rint_Java Math rint() 使用方法及示例