范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

聊聊C右值引用和移动构造函数

  一: 背景
  最近在看 C++ 的右值引用和移动构造函数,感觉这东西一时半会还挺难理解的,可能是没踩过这方面的坑,所以没有那么大的深有体会,不管怎么说,这一篇我试着聊一下。 二: 右值引用1. 它到底解决了什么问题?
  在其他编程语言中,很少听到  右值引用   这个词,我个人感觉还是 C++   这个 值类型   优先的语言基因决定的,我们都知道 值类型   作为方法参数或者返回值时会生成自身的副本,如果 值类型   很大,那一来一回生成若干个深复制的 临时对象 将会产生巨大的性能开销。
  总结一句话: 右值引用   就是尽可能的减少这中间 临时对象   个数,尤其是关联到 heap 上的对象,仅此而已。2. 右值引用是个什么样子?
  说到  右值引用   得先说什么是 右值,左值   , 左值   一般都是带有内存地址的变量,而 右值   一般是立即数或者运算过程中的临时对象,这种对象不会有地址值,是不是很绕,我举个例子吧。 int main() { 	int i = 10; 	int j = 11;  	int sum = i + j; }  10,11,(i+j)
  属于右值,因为它本身没有内存地址,除非把它们放入到栈中或者堆中。 i,j,sum
  属于左值,因为它们是线程栈上地址的标识符。
  知道了  左右值   概念,接下来理解 左右值引用   就很简单了,既然是 引用  ,必然是多个变量指向同一个地址,对吧,修改下代码如下: int main() { 	int i = 10; 	int& k = i;		//左值引用   	int&& m = 10;	//右值引用 }
  接下来看下汇编代码:      33: 	int i = 10; 00FB182F  mov         dword ptr [ebp-0Ch],0Ah       34: 	int& k = i;	 00FB182F  mov         dword ptr [ebp-0Ch],0Ah   00FB1836  lea         eax,[ebp-0Ch]   00FB1839  mov         dword ptr [ebp-18h],eax       36: 	int&& m = 10;	 00FB183C  mov         dword ptr [ebp-30h],0Ah   00FB1843  lea         eax,[ebp-30h]   00FB1846  mov         dword ptr [ebp-24h],eax
  从汇编代码看,它们是一模一样的,也就是说在汇编层面,其实并没有  右值引用   和 左值引用   一说。
  有了这些基础,我们来看下更复杂的 class 结构。 三: 右值引用如何减少对象的创建1. 简要思路
  其实仔细想一想,减少临时对象的创建,无非就是在运算过程中复用一些对象,不需要每次都走赋值构造函数来进行深复制,画个图就像下面这样。
  明白了这个思路,接下来我们举一个例子说明。 2. 一个简单的例子
  C++ 最烦的地方就是有太多的 构造函数  , 数不胜数,太尴尬了,这里我做一个简单的 +   操作例子。  #include  #include   using namespace std;  class StringBuidler { public: 	char* str; 	int length; public: 	StringBuidler() {} 	StringBuidler(int len, char c) { 		this->str = new char[len]; 		this->str[0] = c; 		this->length = len; 	}  	StringBuidler(const StringBuidler& s) {  		printf("StringBuidler:深复制  "); 		this->length = s.length; 		this->str = new char[s.length];  		for (size_t i = 0; i < length; i++) 		{ 			this->str[i] = s.str[i]; 		} 	}  	StringBuidler operator+(const StringBuidler& p) {  		StringBuidler tmp;  		tmp.length = this->length + p.length; 		tmp.str = new char[tmp.length];  		int index = 0;  		for (size_t i = 0; i < this->length; i++) 		{ 			tmp.str[index++] = this->str[i]; 		} 		for (size_t i = 0; i < p.length; i++) 		{ 			tmp.str[index++] = p.str[i]; 		}  		return tmp; 	} };  int main() { 	StringBuidler s1(10, "a"); 	StringBuidler s2(5, "b");  	StringBuidler s3 = s1 + s2;  	printf("s3.length=%d, s1.length=%d, s2.length=%d  ", s3.length, s1.length, s2.length); }  折叠
  从这个例子中可以看到, s1+s2   操作中出现了一次 深copy  ,具体代码出现在 return   处,汇编代码如下:
  因为是深复制,所以会再次生成一个  new char[]   ,如果 new char[]   很大,那将会是不必要的性能开销,能不能像我画的图一样,将 s3 中的 str   指针直接指向 tmp 所持有的 heap 上的 char[]   数组来达到复用目的呢? 肯定是可以的。3. 性能优化方案
  这里需要用  右值引用   + 移动构造函数   让 s3.str   指向 tmp.str  ,从而避免复制构造函数,在 StringBuilder 类中加一个方法如下: 	StringBuidler(StringBuidler&& s) { 		this->str = s.str; 		this->length = s.length;  		s.str = nullptr; 	}
  然后把程序跑起来,截图如下:
  可以看到,深复制已经没有了,这个过程会在  return   处被调用,编译器会判断如果是右值的话,自动走 移动构造函数  ,没有这个函数就会走 赋值构造函数  。四: 总结
  总之  右值引用   可以让你尽可能的复用一些中间对象,达到一个性能上的提升,其实对 C# 程序员来说,这么简单的引用赋值,C++ 搞出了这么多概念,真的很难理解,可能还是那句话,这是 C++ 的值类型优先的基因决定的。

宝宝一看某些人就哭,是怎么回事?不是认生,这些原因要知道幼儿的情绪是最难琢磨的,尤其像刚刚出生的幼儿还不懂得表达,家长们无法理解幼儿的需求,总是会使得宝宝无端的哭闹。当幼儿哭闹时,家长们对此常常束手无策,无法找到根由,有时某些幼儿在看到宝宝可以戴银手镯吗?最近大家对宝宝是否可以佩戴银手镯有很大的争议。很多儿科医生不建议戴银手镯。那到底能不能戴呢?其实主要原因在这里,大家了解一下,作为参考。争议1银手镯含铅含锡这些元素对宝宝身体有害。大脑为何要删除3岁前的记忆?小时候看到了啥?科学家给出答案先问大家一个问题你对童年的最早记忆是什么?发生在几岁?有没有发现,自己对于3岁以前的记忆非常模糊,几乎想不起自己小时候经历的各种事情,甚至有的人最早只能回忆到9岁左右的事。03岁那幼小幼儿英语自然拼读(伴鱼自然拼读)每日更新,为防止资料丢失,请右上角点击关注,更多实用内容持续上传!在育儿路上难的从来都不是搜集学习资源,而是归纳整理消化吸收这些资源,以及如何带动孩子持之以恒地去学习。把我们的时间真搞不明白!房间小没收纳的空间,那为何不选这样的组合床呢?上下虽有不足之处,但设计合适,能拯救一个窄小的空间哟!就好比下方的衣帽间组合床的设计一样,满满的收纳,让人看了爱不释手。超级适合放在小房间里当收纳藏宝箱的组合床以环保为主,让孩子度酒店长包房老曲还需新唱民生周刊全媒体记者于海军全文2290字,阅读约需2分钟长包房提供的服务以及传递的租客理念,将是未来部分酒店发展的一种趋势。疫情期间,经济型酒店如何更好地活下去是个问题。不同于高档酒来1988国际体育小镇,感受体育与美食的碰撞夏日炎炎,酷暑难耐今日为您推荐一处集体育文化商业园区为一体的网红打卡地1988国际体育小镇具体位置1988国际体育小镇位置北京市通州区永顺镇潞苑南大街5号这个以体育为主题的特色商业红魔7S系列新机性价比超高,红魔7跌至乞丐价,友商直呼笑哭2022年7月11日,专业游戏装备品牌红魔鬼举行了主题为满级恶魔,稳帧制胜的红魔鬼7S系列及游戏装备新品发布会。本次发布会上,不仅有边框极为稳定的红魔7S系列游戏旗舰手机,更有掀起viviX80系列的中杯和大杯有什么区别,同配置竟然有1800的差价vivoX系列的颜值一直都很在线,而且一代更比一代的颜值好看,特别是近三款x60x70和x80这三个系列,在颜值上一代更比一代漂亮?不仅在颜值上漂亮,在性能上同样有不错的表现!比如iPhone14系列新机加速曝光,iPhone13闻声价崩开启疯抢新模式随着时间的推移,距离iPhone的发布会已经只有两个月左右了,关于这款重磅机型的消息也是越来越多了,本文就来做一个详细的汇总,消息来源均为较为可靠的消息源。值得一提的是,由于iPh女人会不会打扮看她的颈部就知道了,学会这些思路,优雅又精致会穿衣的女人对时尚都有一定程度的了解,而且知道如何去打扮自己才能发挥魅力,特别是在细节感的塑造上很出众。比如颈部处的处理,女人会不会打扮,看这一点就知道了。下面我们就来看看有哪些值
马伊琍难得精心打扮,穿T恤配喇叭裤简约高级,戴贝雷帽更洋气说到中年女演员当中的实力派的话相信很多人都首先就会想到马伊琍的名字,在同年龄段的女演员群体当中她的演技属于天花板的级别,基本上每次参演的影视剧都能够看到她精彩的表现,不过相对于演技2022年女生购买手机推荐(35005000价位)本次推荐的机型有小米12荣耀60ProOPPOReno7Pro华为P50三星GalaxyS21FE小米12(小尺寸轻薄旗舰)推荐指数优势外观漂亮有质感顶级性能,高通骁龙8Gen1L游览哥斯达黎加时必须尝试的食物任何去过哥斯达黎加的人都会告诉你,它只是你可以参观世界上最美妙的地方之一。人们非常友好和热情,整体氛围非常轻松,正如该国著名的短语所概括的那样puravida,意思是纯粹的生活。除这些爽肤水补水保湿,收缩毛孔,调理皮肤提亮,令肌肤变嫩变白皙这些爽肤水补水保湿,收缩毛孔,调理皮肤提亮,令肌肤变嫩变白皙!WHOO津律享水丰厚的露珠状,琼浆玉液般的质地。看着醇厚,是并不油腻,吸收很快。津律享是WHOO里面适合熟龄肌肤的高端不愿与肌肉腿和解?那就试试这条超遮肉的微喇鲨鱼裤夏天快来啦姐妹们是不是开始运动了!然鹅肌肉腿泰痛苦了越锻炼腿越粗呜呜小腿上有肌肉穿裙子露腿会不好看而其他裤子闷热又普通划重点!显瘦又遮肉的微喇鲨鱼裤才是真的心头好这条微喇裤的版型超有脂肪肝,更得吃早餐浙大医学院第一附属医院学者研究发现,如果有脂肪肝,再不吃早餐,则心血管死亡风险增加。研究纳入参加第三次全国健康和营养检查调查的9926人,其中3004人存在代谢功能障碍相关脂肪肝。小婴儿的呵护重点,每一步都至关重要,做对了大有好处小宝贝刚出生,直到满月,这个时段才叫新生儿。新生儿时期。首要的就是疫苗接种。接种疫苗的关键点就是按时,有特殊情况要及时补上,不要影响后期的疫苗接种时间。1。新生儿基本都在睡觉,不要婴儿睡觉头摇来摇去,后脑勺秃一片,是不舒服还是好玩?家里的大宝二宝,大概从2个月开始就会开启一个奇奇怪怪的现象。比如每次一躺在床上头就会摇来摇去,像似头痒似的,后脑勺也会光秃秃的一片。婆婆每次见到就会唠叨这孩子将来不会是个秃子吧!我500个富贵才气的婴儿起名大全男孩名字茂勋航伟和惬允弦浩壤同光慕睿黎晨英纵云鸣少韬鸿波正雅文博锐利天廷钧麟曜瑞中震越彬永望鹏池建茗曜灿靳言阳星离卿嘉颖容璟翰林锦宇黎昕鹏煊修德弘大彭魄文宇运升墨然靖琪昊东智志辰夜为什么中医讲究辨证?高血压中医如何辨证施治今天与大家分享高血压的中医辨证,高血压是一类多因素影响的复杂慢性疾病,中医证素对高血压如何认识?如何理解?如何进行辨证论治?我总是说辨证用药,辨证施治,辨证到底是什么?辨证是中医学南奥塞梯现状,带你看看真实的南奥塞梯南奥塞梯在高加索山的南部,高加索山的北部是北奥塞梯,相对来说南奥塞梯是人口少,当地人主要以农牧为主,并且多山地,可耕地面积仅占百分之十左右。南奥塞梯与格鲁吉亚当局发生过冲突,实质性