【C++】拷贝对象时,编译器的偷偷优化

你知道吗?对于连续的”构造+拷贝构造“,编译器其实是会默默做出优化的。👻

如果你不知道这个知识点的话,那下面这道笔试题就要失分了😵。

本篇分享一个关于编译器优化的小知识,看完本篇,你就能知道程序里的 构造函数、拷贝构造函数 究竟被调了几次~

题目引入

某笔试题:下面的程序经历了几次构造?几次拷贝构造?

答案为:

1次构造,4次拷贝

对此题的分析在本篇末尾。如果你对这道题尚有存疑,那相信看完本篇,你的疑惑将会烟消云散~👻

传值传参 的优化

我们知道,传值传参会产生拷贝,因为这样能保证 函数内部对参数的操作 不会影响到原始变量的值。

➡️先看一个没做优化的例子:

class W
{
public://构造函数W(int w) :_w(w){cout << "W()" << endl;}//拷贝构造函数W(const W& w) :_w(w._w){cout << "W(const W& w)" << endl;}//析构函数~W(){cout << "~W()" << endl;}
private:int _w;
};
void func(const W w) {}
int main()
{W w1=1;  //构造func(w1);   //拷贝构造:把w1的值拷贝一份,传到形参return 0;
}

调用情况我们打印出来:

可见这种情况下:

W w1=1;
func(w1);

是老老实实调用构造+拷贝构造的,并没有做出优化。

➡️再看一个做了优化的例子:

class W
{
public://构造函数W(int w) :_w(w){cout << "W()" << endl;}//拷贝构造函数W(const W& w) :_w(w._w){cout << "W(const W& w)" << endl;}//析构函数~W(){cout << "~W()" << endl;}
private:int _w;
};
void func(const W w) {}
int main()
{func(W(1));  //一个表达式步骤中,有连续的”构造+拷贝构造“return 0;
}

结果:

我们发现:这次没调拷贝构造了!看来编译器做了优化。

原本,这个表达式的执行顺序是:W(1)先构造出一个W,这个W再拷贝构造,传递给形参,参与表达式func()。

func(W(1));

而编译器做出了优化:

将连续的 构造+拷贝构造 优化成一步构造。

动图可以更直观地看出来:

传匿名对象 的优化

我们学过的匿名对象,也是可以传参过去的,它的优化和刚刚讲的传值传参的优化 道理是一样的。

class W
{
public:W() {cout << "W()" << endl;}W(const W& w) {cout << "W(const W& w)" << endl;}~W(){cout << "~W()" << endl;}
};
void f1(W w) {
​
}
int main()
{f1(W());   //先构造一个匿名对象,然后作为参数 传值传参过去return 0;
}

结果:

依然没调用拷贝构造。

看看程序怎么运行的:

还是刚刚讲的,这是因为编译器的优化,将 构造+拷贝构造 直接优化成了 一步构造。

结论:一个连续的表达式步骤中,连续构造一般都会被优化。

传值返回

可以优化的情况:

class W
{
public://构造函数W(int w=0) :_w(w){cout << "W()" << endl;}//拷贝构造函数W(const W& w) :_w(w._w){cout << "W(const W& w)" << endl;}//析构函数~W(){cout << "~W()" << endl;}
private:int _w;
};
​
W func() {W ret;  //1次构造return ret;  //1次拷贝构造:将ret的值通过拷贝构造返回
}
​
int main()
{W w1=func();  //W w1=……仍是一次拷贝构造。所以按理说是“1构造+2拷贝构造”return 0;
}

然而实际上只进行了“1构造+1拷贝构造”:

为什么拷贝构造从2次变成了1次?

原来,这也是编译器的优化,它会将两个拷贝构造,优化成一个。

这里用图说明一下:

不能优化的情况

上面这种情况和下面的这种要区分,下面这种是不能优化的:

class W
{
public://构造函数W(int w=0) :_w(w){cout << "W()" << endl;}//拷贝构造函数W(const W& w) :_w(w._w){cout << "W(const W& w)" << endl;}//赋值运算符W& operator=(const W& w) {cout << "W& operator=(const W& w)" << endl;if (this != &w) {_w = w._w;}return *this;}//析构函数~W(){cout << "~W()" << endl;}
private:int _w;
};
W func() {W ret;return ret;
}
​
int main()
{W w1; w1 = func();  //赋值接收对象return 0;
}

这种是分4步进行的:

可见,赋值接收对象 不如 拷贝构造的方式接收。后者可以被优化。

总结

1.连续的 构造和拷贝构造 会被优化成 直接调用构造。(分步的就无法优化了)

2.产生的临时变量往往会被优化掉。

题目的解析

我们现在回过头看看一开始那道题:

首先,W x;是1次构造。

然后,f(x)会把x的值拷贝给u,是1次拷贝构造。

在函数f(W u)里,v的实例化是1次拷贝构造.

w究竟是拷贝构造还是赋值的呢?因为w原先不存在,所以不是赋值,是1次拷贝构造。

return w;(这里最易错) 原本是要拷贝产生临时变量,再用临时变量拷贝构造出y的。但经过编译器的优化,升级成一步拷贝构造。

所以,一共1构造+4拷贝构造。

把这题升级一下:

几次构造?几次拷贝构造?

和上题同理,只不过这次return w将连续的三步优化成一步。

答案:1次构造 7次拷贝构造

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/130480.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华为云云耀云服务器L实例评测|使用宝塔面板管理服务器教学

目录 一、概述 1.1 华为云云耀云服务器L实例 1.2 BT&#xff08;宝塔&#xff09; 1.3 资源和成本规划 二、购买云耀云服务器L实例并进行相关配置 2.1 购买云耀云服务器L实例 2.2 设置服务器密码 2.3 配置安全组 2.4 设置Nginx安全级别 三、初始化宝塔面板 3.1 获取密…

docker安装mysql、clickhouse、oracle等各种数据库汇总

1&#xff1a;docker 安装mongo数据库并使用 官网&#xff1a;https://www.mongodb.com/docs/manual/ mongo shell教程1&#xff1a;http://c.biancheng.net/mongodb2/connection.html 安装1 &#xff1a;https://www.zhihu.com/question/54602953/answer/3047452434?utm_id0…

开发指导—利用组件插值器动画实现 HarmonyOS 动效

一. 组件动画 在组件上创建和运行动画的快捷方式。具体用法请参考通用方法。 获取动画对象 通过调用 animate 方法获得 animation 对象&#xff0c;animation 对象支持动画属性、动画方法和动画事件。 <!-- xxx.hml --><div class"container"> <di…

做一个长期主义者,我开始尝到甜头!

01 今年国庆节&#xff0c;有两位亲戚结婚&#xff0c;计划着要老家。 说真的&#xff0c;从前的我&#xff0c;特别害怕聚会吃饭。 特别的尬&#xff0c;不知道说啥子&#xff0c;好像也没有什么好说的。 我在亲戚眼中&#xff0c;是个安静、害羞、老实的乖娃娃。 嗯&#xff…

分享一下公众号抽奖活动怎么做

公众号抽奖活动是一种非常有效的营销手段&#xff0c;可以吸引大量粉丝关注&#xff0c;同时提高品牌曝光度和用户粘性。下面将介绍公众号抽奖活动的制作方法&#xff0c;包括活动规则制定、奖品设置、参与方式和开奖方式等步骤。 一、活动规则制定 制定活动规则是制作抽奖活动…

Linux工具——gcc

目录 一&#xff0c;gcc简介 二&#xff0c;C语言源文件的编译过程 1.预处理 2.编译 3.汇编 4.链接 5.动静态库 一&#xff0c;gcc简介 相信有不少的小白和我一样在学习Linux之前只听说过visual studio。其实这个gcc这个编译器实现的功能便是和visual studio一样的功能&…

【漏洞复现】E-office文件包含漏洞

漏洞描述 Weaver E-Office是中国泛微科技(Weaver)公司的一个协同办公系统。泛微 E-Office 是一款标准化的协同 OA 办公软件,实行通用化产品设计,充分贴合企业管理需求,本着简洁易用、高效智能的原则,为企业快速打造移动化、无纸化、数字化的办公平台。 该漏洞是由于存在…

VR电气低压试验仿真教学系统软件激发学生的学习兴趣

智慧化时代&#xff0c;电力设备试验仿真培训也逐渐与先进科技相结合&#xff0c;借助VRAR技术创造一个高逼真、安全、沉浸感的实验和设计平台。 在虚拟环境中&#xff0c;元宇宙VR会模拟各种触电场景&#xff0c;比如大风刮断架空线、接户线搭落在金属物、相线和电杆拉线褡裢、…

day56补

583. 两个字符串的删除操作 力扣题目链接(opens new window) 给定两个单词 word1 和 word2&#xff0c;找到使得 word1 和 word2 相同所需的最小步数&#xff0c;每步可以删除任意一个字符串中的一个字符。 示例&#xff1a; 输入: "sea", "eat"输出: …

GcExcel:Java 应用创建、修改和保存 Excel 电子表格 -Crack

在 Java 应用程序中创建、修改和保存 Excel 电子表格&#xff1a; GrapeCity Documents for Excel&#xff0c;Java 版 (GcExcel) 是一个高速 Java Excel 电子表格 API 库&#xff0c;不需要依赖于 Microsoft Excel。用户可以通过 Java 应用程序以编程方式创建、编辑、导入和导…

2020-2022年低纬高原区典型种养殖区氮磷干湿沉降数据集

摘要 氮磷干湿沉降是指大气中氮磷通过沉降方式到达地面,进入陆地生态系统物质循环的过程,干湿沉降在环境氮磷污染输入中占据重要比例。我国是种养殖业大国,摸清源于种植业和养殖业氮磷干湿沉降负荷,对评估氮磷干湿沉降生态效应,指导环境污染治理,促进种养殖业绿色发展具有…

无涯教程-JavaScript - PMT函数

描述 PMT功能基于固定的还款额和固定的利率来计算贷款的还款额。 语法 PMT (rate, nper, pv, [fv], [type])争论 Argument描述Required/OptionalRateThe interest rate for the loan.RequiredNperThe total number of payments for the loan.RequiredPv 现在的价值,或一系列…

一个患有精神分裂症程序员,用10年写了一个“拯救世界”的操作系统

操作系统是一个极其复杂的软件&#xff0c;一个人开发的话工作量特别吓人。 但是一个患有精神分裂症的天才程序员Terry Davis&#xff0c;宣称接到了来自上帝的指示&#xff1a;你要建立一座神庙&#xff0c;用操作系统的方式。 于是&#xff0c;Terry整整花了10年时间&#x…

Python经典小游戏02:字母数字代码雨

★★★★★博文创作不易&#xff0c;我的博文不需要打赏&#xff0c;也不需要知识付费&#xff0c;可以白嫖学习编程小技巧。使用代码的过程中&#xff0c;如有疑问的地方&#xff0c;欢迎大家指正留言交流。喜欢的老铁可以多多点赞收藏分享置顶&#xff0c;小红牛在此表示感谢…

系统架构设计师(第二版)学习笔记----嵌入式系统及软件

【原文链接】系统架构设计师&#xff08;第二版&#xff09;学习笔记----嵌入式系统及软件 文章目录 一、嵌入式系统1.1 嵌入式系统的组成1.2 嵌入式系统的特点1.3 嵌入式系统的分类 二、嵌入式软件2.1 嵌入式系统软件分层2.2 嵌入式软件的主要特点 三、安全攸关软件的安全性设…

【前端项目】博客系统(页面设计)

文章目录 一、预期效果二、实现博客列表页三、实现博客正文页四、实现博客登录页五、实现博客编辑页 一、预期效果 代码详情见&#xff1a;gitee链接 &#x1f495; 博客列表页效果 &#x1f495; 博客详情页效果 &#x1f495; 博客登录页效果 &#x1f495; 博客编辑页效果…

首个国家级元宇宙计划发布,和数集团迎来赛道发展新机遇

近日&#xff0c;工业和信息化部、教育部、文化和旅游部、国务院国资委、国家广播电视总局办公厅五部门联合印发《元宇宙产业创新发展三年行动计划&#xff08;2023-2025年&#xff09;》&#xff08;以下简称《计划》&#xff09;&#xff0c;其中在发展目标中提到要培育3-5家…

【C++】哈希——哈希的概念,应用以及闭散列和哈希桶的模拟实现

前言&#xff1a; 前面我们一同学习了二叉搜索树&#xff0c;以及特殊版本的平衡二叉搜索树&#xff0c;这些容器让我们查找数据的效率提高到了O(log^2 N)。虽然效率提高了很多&#xff0c;但是有没有一种理想的方法使得我们能提高到O(1)呢&#xff1f;其实在C语言数据结构中&a…

服务器数据恢复-EMC存储磁盘损坏的RAID5数据恢复案例

服务器数据恢复环境&#xff1a; 北京某单位有一台EMC某型号存储&#xff0c;有一组由10块STAT硬盘组建的RAID5阵列&#xff0c;另外2块磁盘作为热备盘使用。RAID5阵列上层只划分了一个LUN&#xff0c;分配给SUN小机使用&#xff0c;上层文件系统为ZFS。 服务器故障&#xff1…

【语义分割 01】Open MMLab介绍

1 Tutorial https://github.com/TommyZihao/MMSegmentation_Tutorials https://github.com/TommyZihao/Train_Custom_Dataset https://github.com/TommyZihao/aidlux_tutorial OpenMMLab是一个由中国开发者主导的具有世界影响力的人工智能计算机视觉开源算法体系, 至今已经开…