编译器对连续构造的优化

news2024/10/17 2:55:29

一:优化的规则

在一行代码中连续进行:构造+构造/构造+拷贝构造/拷贝构造+拷贝构造   都会合二为一

如下:

a:构造+构造->构造

b:构造+拷贝构造->构造

c:拷贝构造+拷贝构造->拷贝构造

注意:不同的编译器优化的效果可能会不同(博主是在 VS19 下的 Debug 版本下进行演示)

二: 优化展示

以下是一个用于测试的类A,其有构造函数,拷贝函数,赋值重载函数,构析函数,进入每个函数都会打印调用了一次 xx函数 的字眼,这样更能显式的看出优化

class A
{
public:
	//构造函数
	A(int a = 0)
		:_a(a)
	{
		cout << "A(int a)调用一次构造" << endl;
	}

	//拷贝函数
	A(const A& aa)
		:_a(aa._a)
	{
		cout << "A(const A& aa)调用一次拷贝" << endl;
	}

	//赋值重载函数
	A& operator=(const A& aa)
	{
		cout << "A& operator=(const A& aa)调用一次赋值" << endl;

		if (this != &aa)
		{
			_a = aa._a;
		}

		return *this;
	}

	//构析函数
	~A()
	{
		cout << "~A()调用一次构析" << endl;
	}
private:
	int _a;
};

①:在一行代码的构造+拷贝

情况1:
int main()
{
	A aa1 = 1;

	return 0;
}

解释:

a:aa1是A类实例化的对象,而1是整形,这叫作类型转换

b:类型转换 的规则如下:

所有的类型转换都是不会影响到本身的,图中来说就是不会影响到1,并不是1真的变成了一个对象,而是1先作为参数进行了匿名构造,构造出一个中间的对象(且中间变量都是具有常属性,即不能被更改),然后这个中间对象再去进行拷贝构造出了aa1(用一个已存在的对象去初始化一个未存在的对象,调用拷贝构造)

c:所以这里在同一行代码中进行构造+拷贝构造,所以优化成了:

结果:

解释:正如前文的规则,优化成了只调用了一次构造(构析是aa1出了main函数调用了)

Q:为什么不是直接进行拷贝构造呢?为什么要生成中间变量?不会压根没有中间变量的生成吧?

A:如果没有中间变量的生成,那从1到aa1就应该是变量到变量,那为何以下这样写不行呢?

A& aa1 = 1;

这样不是只是对生成的aa1进行了引用而已吗?为什么就不行了呢。报错如下:

正确写法:

const A& aa1 = 1;

解释:const修饰的是常变量,具有不可变的性质,只能这样写也说明了,的确是有中间变量的产生,其进行拷贝构造给了aa1,因为中间变量是有常属性的,我们的aa1被常属性的对象初始化,所以我们的aa1的引用才需要const修饰

情况2:
void func(A aa1)
{

}

int main()
{
	//匿名构造仅是构造(不是类型转换,谈何构造加拷贝),然后再拷贝传参
	func(A(2));

	return 0;
}

解释:

a:func(A(2)),中的A(2)是一次匿名构造,调用了一次构造函数

b: A(2)构造出来的对象传入func函数,调用了一次拷贝函数

c:所以是一次构造 + 拷贝,但是是在同一行上连续进行的,所以优化成了:

情况3:
void func(A aa1)
{

}
//构造+拷贝构造->构造 
int main()
{
	//3 到 aa1 是隐示类型转换 先构造 在拷贝
	func(3);

	return 0;
}

解释:

a:3直接作为参数给func函数的aa1接收,这是类型转换,如情况1中的意义,先进行构造,再进行拷贝,所以 应该是 在一行上进行 构造 + 拷贝,优化成了:

②:不在一行的的构造 + 拷贝

void func(A aa)
{

}

int main()
{
	A aa1(1);

	func(aa1);

	return 0;
}

解释:

a:A aa1(1),是一次构造函数的调用

b:func(aa1),将aa1传给了func函数,是一次拷贝函数的调用

c:所以这是  构造 + 拷贝函数 ,但是不会被优化,因为其不是在一行上连续进行的

结果:

两次构析是aa 和  aa1 离开自己的作用域调用的

③:在一行的的拷贝+ 拷贝

A func()
{
	A aa;
	return aa;
}

int main()
{
	
	A aa1 = func();

	return 0;
}

解释:

a:func函数中 aa是一次构造,return aa 是一次拷贝 ,A aa1 中的 aa1 还未存在,此时去接受 func函数return 出来的对象,这是一次拷贝,演示后两次拷贝的优化效果

结果:

 

解释:后两次拷贝优化成了一次

 ④:不在一行的的构造+构造

A func()
{
	A aa;
	return aa;
}

int main()
{

	A aa2;
	aa2 = func();

	return 0;
}

解释:

a:A aa2是调用一次构造 

b:func 则进入函数,A aa 是一次构造 

c:return aa 是一次拷贝

d: 函数返回的对象给 aa2 是一次赋值(两个存咋的对象用 = 叫作赋值)

这个对前两次的构造进行展示,因为不是一行上的连续构造,所以不进行优化

结果:

总结:

一行上连续的构造 + 构造 =  一次构造 

一行上连续的构造 + 拷贝 =  一次构造

一行上连续的拷贝 + 拷贝 =  一次拷贝

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

KubeSphere v4 安装指南

日前&#xff0c;KubeSphere v4 发布&#xff0c;相较于之前的版本&#xff0c;新版本在架构上有了颠覆性的变化。为了让社区的各位小伙伴能够丝滑的从旧版本过渡到新版本&#xff0c;我们特别推出本篇安装指南文章&#xff0c;以供参考。 关于 KubeSphere v4 的介绍&#xff…

施磊C++ | 进阶学习笔记 | 5.设计模式

五、设计模式 文章目录 五、设计模式1.设计模式三大类型概述一、创建型设计模式二、结构型设计模式三、行为型设计模式 2.设计模式三大原则3.单例模式1.饿汉单例模式2.懒汉单例模式 4.线程安全的懒汉单例模式1.锁双重判断2.简洁的线程安全懒汉单例模式 5.简单工厂(Simple Facto…

MySQL 8.4修改user的host属性值

MySQL 8.4修改user的host属性值 update mysql.user set host localhost where user mysql用户名; MySQL 8.4修改初始化后的默认密码-CSDN博客文章浏览阅读804次&#xff0c;点赞6次&#xff0c;收藏11次。先下载mysql的zip压缩包&#xff1a;MySQL :: Download MySQL Communi…

(CWRU)轴承故障诊数据集和代码全家桶

包括 完整的CWRU轴承故障数据集&#xff0c; 以及已经生成制作好的一维故障信号数据集、时频图像数据集&#xff0c;对应代码均可以运行 点击下载&#xff1a;数据集和代码全家桶 环境&#xff1a;python 3.9 任何环境安装或者代码问题&#xff0c;请联系作者沟通交流&#xf…

操作符详解(C 语言)

目录 一、操作符的分类二、算数操作符1. 除法操作符2. 取余操作符 三、位移操作符1. 进制2. 原码、反码和补码3. 左移操作符&#xff08;<<&#xff09;和右移操作符&#xff08;>>&#xff09; 四、位操作符1. 按位与 &2. 按位或 |3. 按位异或 ^4. 按位取反 ~…

2018 年 NLP 的 10 个令人兴奋的想法

一、说明 这篇文章收集了有影响力的 10 个想法&#xff0c;我们将来可能会看到更多。 对于每个想法&#xff0c;我们将重点介绍 1-2 篇执行良好的论文。为了保持列表简洁&#xff0c;这里没有涵盖所有相关工作。该列表必然是主观的&#xff0c;涵盖主要与迁移学习和泛化相关的想…

老照片修复工作流教程:用 ComfyUI 轻松还原历史记忆

你是否有过这样的遗憾&#xff1f; 那些珍贵的老照片因为时间的流逝&#xff0c;早已失去了当年的色彩&#xff0c;变得模糊、褪色&#xff0c;甚至破损&#xff1f; 今天带你了解如何使用 ComfyUI 的老照片修复工作流&#xff0c;通过简单的几步操作&#xff0c;在短短十几秒…

三亚旅游微信小程序的设计与实现

详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不…

【深度学习代码调试1】环境配置篇(上) -- 安装PyTorch(安利方法:移除所有国内源,使用默认源)

【深度学习代码调试1】环境配置篇 -- 安装TensorFlow和PyTorch 写在最前面1. 创建新的Conda环境2. 安装PyTorch及相关库&#xff08;可以直接跳到2.3安装方法&#xff09;2.1 检查CUDA版本2.2 解决安装过程中常见问题2.2.1 超时问题&#xff08;这个不是最终解决方案&#xff0…

AUTOSAR_EXP_ARAComAPI的5章笔记(13)

☞返回总目录 5.4.7 事件&#xff08;Events&#xff09; 在骨架侧&#xff0c;服务实现负责通知事件的发生。如 5.4.2 RadarService Skeleton Class 所示&#xff0c;骨架为每个事件提供一个事件包装类的成员。骨架的事件包装类与代理的事件包装类看起来明显不同。 在骨架端…

论文阅读:On determining the hinterlands of China‘s foreign trade container ports

集装箱港口腹地的边界线&#xff0c;只要存在&#xff0c;就可以作为未来港口发展和基础设施规划的参考点。在早期划定中国港口腹地的努力中&#xff0c;要么考虑的港口数量有限&#xff0c;要么仅根据港口总吞吐量划定腹地。因此&#xff0c;这些研究都没有让我们清楚地了解共…

快速理解AUTOSAR CP的软件架构层次以及各层的作用

在 AUTOSAR CP 的架构中&#xff0c;软件分为 应用层 (App)、运行时环境 (RTE) 和 基础软件层 (BSW) 三个主要层级。下面是每一层的主要功能与简单的代码示例来展示它们之间的关系。 1. 概述 应用层 (App)&#xff1a;包含应用程序代码&#xff0c;主要实现业务逻辑。应用层通…

DeepFM模型代码详解

直到看到这篇文章&#xff0c;我才搞明白类别特征怎么做lookup的&#xff0c;也看明白了代码逻辑。如果你看完没懂&#xff0c;私信留下wx&#xff0c;给你讲懂。 1、Deepfm 的原理&#xff0c;DeepFM 是一个模型还是代表了一类模型&#xff0c;DeepFM 对 FM 做了什么样的改进…

【时时三省】(C语言基础)函数介绍strcat

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 strcat 字符串追加 示例&#xff1a; 比如我要把world加到hello后面去 就可以用这个 还有一种方法是这样 这两个代码的意思是一样的 只是写法不一样 写的时候要注意这些 •源字符串必须…

DAB-DETR: DYNAMIC ANCHOR BOXES ARE BETTER QUERIES FOR DETR论文笔记

原文链接 [2201.12329] DAB-DETR: Dynamic Anchor Boxes are Better Queries for DETR (arxiv.org)https://arxiv.org/abs/2201.12329 原文笔记 在本文中&#xff0c;我们提出了一种新的查询公式&#xff0c;使用动态锚框进行DETR (DEtection TRansformer)&#xff0c;并对查…

探索人工智能在数学教育上的应用——使用大规模语言模型解决数学问题的潜力和挑战

概述 论文地址&#xff1a;https://arxiv.org/abs/2402.00157 数学推理是人类智能的重要组成部分&#xff0c;人工智能界不断寻求应对数学挑战的方法&#xff0c;而在这一过程中&#xff0c;人工智能的能力需要进一步提高。从文本理解到图像解读&#xff0c;从表格分析到符号操…

大数据|MapReduce编程原理与应用

在大数据时代的浪潮中&#xff0c;MapReduce作为一种高效处理海量数据的编程模型&#xff0c;自其诞生以来便成为了数据处理领域的基石。本文旨在深入探讨MapReduce的基本原理、典型应用以及其在未来技术发展趋势中的展望&#xff0c;帮助读者更好地理解并应用这一关键技术。 一…

数制转换及交换机

数制转换 非位置化数字系统&#xff1a;罗马数字 位置化数字系统&#xff1a;二进制&#xff0c;八进制&#xff0c;十进制&#xff0c;十六进制 十进制数&#xff1a; 符号&#xff1a;2 2 2位置&#xff1a;2 1 0位权&#xff1a;该数字的真实大小 该位置上的数基数的位置…

如何设计开发RTSP直播播放器?

技术背景 我们在对接RTSP直播播放器相关技术诉求的时候&#xff0c;好多开发者&#xff0c;除了选用成熟的RTSP播放器外&#xff0c;还想知其然知其所以然&#xff0c;对RTSP播放器的整体开发有个基础的了解&#xff0c;方便方案之作和技术延伸。本文抛砖引玉&#xff0c;做个…

所有程序员的白嫖圣地-github

内容汇总 认识github页面如何从github下载资源git配置如何通过github管理工程代码 有人问github怎么用&#xff0c;几分钟了解这个每个程序员都在用的白嫖圣地。 打开github主界面&#xff0c;映入眼帘的是Home面板&#xff0c;它的作用是显示我们关注的人、点赞的项目等更新…