右值引用、移动构造函数和move
右值引用
右值一般指的是无法用&取到存储地址的。比如常量10
那么我们可以使用&&来获得右值
int &&j=10;
int e=10;
int &&j=e;//错误,因为e是左值
移动构造函数
#include <iostream>
using namespace std;
class demo
{
public:demo() :num(new int(0)){cout << "construct!" << endl;}//拷贝构造函数demo(const demo &d) :num(new int(*d.num)){cout << "copy construct!" << endl;}~demo(){if(num != nullptr){delete num;num = nullptr;}cout << "class destruct!" << endl;}
private:int *num;
};
demo get_demo()
{return demo();
}
int main()
{demo a = get_demo();return 0;
}
在这个过程中,如果没有经过返回值优化的话,会在get_demo函数return时返回一个临时变量,该临时变量会调用拷贝构造函数从return后面创建的demo对象中得到值,同时demo对象本身销毁;然后demo会再次调用拷贝构造函数从临时对象处赋值,同时也销毁临时对象。这样其实一共调用了一次构造函数(return demo()),两次拷贝构造函数(函数内创建的demo对象赋值给临时变量,临时变量赋值给demo),两次析构函数(临时变量和函数内创建的A对象),每次构造和析构的过程都要new和delete资源,这对于计算来说是极大的浪费。
过程中生成的都是匿名对象,无法通过&获取地址,因此它是一个右值,可以通过引入移动构造函数来优化程序。
可以看到两次深拷贝的过程都是通过移动构造函数来完成的,在移动构造函数中,参数是一个demo的右值引用,并且直接将新生成的对象的指针成员指向匿名对象所申请的堆空间,将匿名对象的成员指针置空,这样就防止每次调用拷贝构造函数向堆上申请新的内存空间了,大大提高了效率。
所谓移动语义,指的就是以移动而非深拷贝的方式初始化含有指针成员的类对象。简单的理解,移动语义指的就是将其他对象(通常是临时对象)拥有的内存资源“移为已用”。
move
默认情况下,左值初始化同类对象只能通过拷贝构造函数完成,如果想调用移动构造函数,则必须使用右值进行初始化。C++11 标准中为了满足用户使用左值初始化同类对象时也通过移动构造函数完成的需求,新引入了 std::move() 函数,它可以将左值强制转换成对应的右值,由此便可以使用移动构造函数。
#include <iostream>
using namespace std;
class MoveDemo
{
public:MoveDemo() :num(new int(0)){cout << "construct!" << endl;}MoveDemo(const MoveDemo &d) :num(new int(*d.num)){cout << "copy construct!" << endl;}//添加移动构造函数MoveDemo(MoveDemo &&d) :num(d.num){d.num = nullptr;cout << "move construct!" << endl;}~MoveDemo(){if (num != nullptr){delete num;num = nullptr;}cout << "class destruct!" << endl;}
public:int *num;
};
MoveDemo get_demo()
{return MoveDemo();
}
int main()
{MoveDemo demo;cout << "demo2:\n";MoveDemo demo2 = demo;//cout << *(demo2.num) << endl; //可以执行cout << "demo3:\n";MoveDemo demo3 = std::move(demo);//此时 demo.num = NULL,因此下面代码会报运行时错误//cout << *(demo.num) << endl;return 0;
}
参考
https://blog.csdn.net/bureau123/article/details/112696446https://www.cnblogs.com/wickedpriest/p/12662746.html
右值引用、移动构造函数和move相关推荐
- 右值引用 移动构造函数 移动语义
一篇讲的很好的博客:https://www.jianshu.com/p/d19fc8447eaa 左值 右值: 看能不能对表达式取地址,如果能,则为左值,否则为右值. 将亡值和纯右值: 左值 右值: ...
- C++11中的右值引用及move语义编程
C++0x中加入了右值引用,和move函数.右值引用出现之前我们只能用const引用来关联临时对象(右值)(造孽的VS可以用非const引用关联临时对象,请忽略VS),所以我们不能修临时对象的内容,右 ...
- C++ 右值引用 | 左值、右值、move、移动语义、引用限定符
文章目录 C++11为什么引入右值? 区分左值引用.右值引用 move 移动语义 移动构造函数 移动赋值运算符 合成的移动操作 小结 引用限定符 规定this是左值or右值 引用限定符与重载 C++1 ...
- C++语法——右值引用、移动构造和赋值、万能引用和转发、move和forward底层实现
目录 一.右值引用 (一).何为右值 (二).右值引用 (三).右值和左值的互相传递 ①左值->右值引用 ②右值->左值引用 (四).右值引用的自身属性 二.移动构造和移动赋值 (一).移 ...
- C++11:右值引用、移动构造、std::move, 以及使用emplace_back代替push_back
最近在写一段代码的时候,突然很好奇C++11中对push_back有没有什么改进以增加效率,上网搜了一些资料,发现果然新增了emplace_back方法,比push_back的效率要高很多. 1.右值 ...
- 左值/右值/左值引用/右值引用/move的用法介绍
目录 问题 左值和右值 概念总结: 需要用到左值的运算符: 引用分类 左值引用 右值引用 右值引用到底什么用? std::move()函数介绍 问题 什么是左值和右值? 什么是左/右值引用? 左/右值 ...
- C++11:右值引用、move, 以及使用emplace_back代替push_back
最近在写一段代码的时候,突然很好奇C++11中对push_back有没有什么改进以增加效率,上网搜了一些资料,发现果然新增了emplace_back方法,比push_back的效率要高很多. 1.右值 ...
- move std 函数 示例_C++11右值引用和std::move语句实例解析(推荐)
右值引用(及其支持的Move语意和完美转发)是C++0x将要加入的最重大语言特性之一.从实践角度讲,它能够完美解决C++中长久以来为人所诟病的临时对象效率问题.从语言本身讲,它健全了C++中的引用类型 ...
- std::move 左值右值 左值引用右值引用
参考:https://blog.csdn.net/daaikuaichuan/article/details/88371948 https://zhuanlan.zhihu.com/p/9458820 ...
- C++右值引用 和 std::move()
void debug(int&& a){return a; } std::move(a) 可以将左值变为右值 int c = 0x100; // c 可以被取地址,c 为左值,c++ ...
最新文章
- 记一次Sonar执行失败的修复
- webpack打包转换es6_webpack(二)解析es6并打包
- xshell中mysql命令大全_Linux之Xshell脚本代码实例
- html缓存特效代码,HTML特效代码
- 为什么要完成量子计算机,我们为啥要量子计算机?
- C++封装、构造函数、析构函数
- linux kill命令详解
- 用代码判断当前系统是否支持某个版本的feature
- 计算机文献双语外文,中英文双语计算机专业毕业设计外文文献翻译成品:对Delphi的概述.docx...
- 智慧城市发展路径中 中国特色是主色调
- AVOD--avod/core/format_checker.py代码理解
- GPT分区和MBR分区切换
- 《Linux篇》超详细安装FinalShell并连接Linux教程
- Vanishing Point Constrained Lane DetectionWith a Stereo Camera (IEEE 2017)
- Android百度地图SDK:隐藏比例尺,隐藏百度LOGO,隐藏缩放控件
- 2008年度十大科技突破
- 首届“网刃杯”网络安全大赛部分WP
- Life:最新上海落户政策(以一名普通研究生为例计分)
- 从50亿图文中提取中文跨模态新基准Zero,奇虎360全新预训练框架超越多项SOTA
- 爬取猫眼票房保存在MySQL_Scrapy爬取猫眼电影并存入MongoDB数据库
热门文章
- python实现文件批量添加重命名
- Python自动化之Django中间件
- vim - 自动补齐
- dw中创建java程序_Java创建对象的过程简介
- micro hdmi引脚定义义_系,意、义、意义,有理数的几何解释,合理存在的数(有理数)...
- 拓端tecdat|MATLAB中的马尔可夫区制转移(Markov regime switching)模型
- 拓端tecdat|R语言使用 LOWESS技术图分析逻辑回归中的函数形式
- 操作系统PV操作题整理2
- socket.io html5 聊天,WebSocket探讨之——socket.io搭建多聊天室
- 如何用pdb命令调试python代码