浅谈编译器对构造函数和拷贝构造的优化

news2025/1/19 11:35:56

一、前言

①我们先看一段程序,传值传参和传引用传参

#include <iostream>
using namespace std;

class D
{
public:
	D(int a=0)//构造
		:_a(a)
	{
		cout << "D(int a=0)" << endl;
	}
	D(const D& d)//拷贝
	{
		_a = d._a;
		cout << "D(const D& d)" << endl;
	}
	~D()//析构
	{
		cout << "~D()" << endl;
	}
private:
	int _a;
 };
void  Func1(D &d)
{

}
void  Func2(D d)
{

}

int main() {
	
	D d;
	printf(".......");
	Func2(d);//传值传参
	printf("...");
	Func1(d);//传引用传参

	return 0;
}

结果 

 可以发现传值传参调用了拷贝构造,传引用传参没有调用拷贝构造

②接着看下面的程序,传值返回和传引用返回

#include <iostream>
using namespace std;

class D
{
public:
	D(int a=0)//构造
		:_a(a)
	{
		cout << "D(int a=0)" << endl;
	}
	D(const D& d)//拷贝
	{
		_a = d._a;
		cout << "D(const D& d)" << endl;
	}
	~D()//析构
	{
		cout << "~D()" << endl;
	}
private:
	int _a;
 };
D  Func1(D &d)
{
	return d;
}
 D& Func2(D& d)
{
	 return d;
}

int main() {
	
	D d;
	printf(".......");
	Func1(d);//传值返回
	printf("...");
	Func2(d);//传引用返回

	return 0;
}

结果:

 可以发现,传值返回会调用拷贝构造函数,传引用返回不会调用拷贝构造函数

总结:传参和传返回值时,如果是引用的话,那么就不会调用拷贝构造函数,否则需要调用拷贝构造函数

二、编译器的优化

①现在开始谈谈编译器的优化,请看下面的程序

#include <iostream>
using namespace std;

class D
{
public:
	D(int a=0)//构造
		:_a(a)
	{
		cout << "构造D(int a=0)" << endl;
	}
	D(const D& d)//拷贝
	{
		_a = d._a;
		cout << "拷贝D(const D& d)" << endl;
	}
	~D()//析构
	{
		cout << "析构~D()" << endl;
	}
private:
	int _a;
 };
void Func(D d)
{}

int main() {
	//D(8)为匿名对象
	Func(D(8));

	return 0;
}

看上面的程序,再想它的运行顺序可以想到,该程序会先调用构造函数初始化匿名对象,然后因为该函数是传值传参,所以要调用拷贝构造将该匿名对象的值拷贝一份给形参。然而,真的是这样执行的吗?

如果要了解匿名对象的相关知识请前往这:匿名对象的相关知识

看结果:

 可以发现它只调用了构造函数,而没有调用析构函数。

②再看看下面的程序

#include <iostream>
using namespace std;

class D
{
public:
	D(int a=0)//构造
		:_a(a)
	{
		cout << "构造D(int a=0)" << endl;
	}
	D(const D& d)//拷贝
	{
		_a = d._a;
		cout << "拷贝D(const D& d)" << endl;
	}
	~D()//析构
	{
		cout << "析构~D()" << endl;
	}
private:
	int _a;
 };
void Func(D d)
{}

int main() {
	//会发生隐式转换 D d = D(2) ;
	D d = 2;

	return 0;
}

根据匿名对象的相关知识可以知道,D d =2;该语句会先调用构造函数初始化匿名对象,然后再调用拷贝构造将匿名对象的值赋给d。

结果:

 可以发现,又和我们预期的结果不一样

③让我们接着看最后一个程序

#include <iostream>
using namespace std;

class D
{
public:
	D(int a=0)//构造
		:_a(a)
	{
		cout << "构造D(int a=0)" << endl;
	}
	D(const D& d)//拷贝
	{
		_a = d._a;
		cout << "拷贝D(const D& d)" << endl;
	}
	~D()//析构
	{
		cout << "析构~D()" << endl;
	}
private:
	int _a;
 };
void Func(D d)
{}

int main() {
	D d1;
	Func(d1);

	return 0;
}

结果:

 可以发现,这时即调用了构造函数又调用了析构函数,为什么和上面的结果不一样呢?

原因:

一个表达式中,连续构造+拷贝构造会被编译器优化为一个只调用一个拷贝构造函数。

ok,关于编译器对构造和拷贝构造函数的优化的知识就分享到这里了,感谢支持

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

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

相关文章

域名到期时间查询网站-免费版的翼龙老域名挖掘

批量域名过期查询软件 随着互联网的不断发展&#xff0c;域名越来越重要&#xff0c;特别是对于那些热爱SEO优化的网站管理员来说&#xff0c;域名的重要性无法忽视。而对于那些热衷于SEO优化的用户来说&#xff0c;域名过期查询可能是一个必不可少的工具&#xff0c;它可以用…

数据结构初阶--链表OJⅡ

目录 前言相交链表思路分析代码实现 环形链表思路分析代码实现 环形链表Ⅱ思路分析代码实现 复制带随机指针的链表思路分析代码实现 前言 本篇文章承接上篇博客&#xff0c;继续对部分经典链表OJ题进行讲解 相交链表 先来看题目描述 思路分析 这道题我们还是首先来判断一…

蓝牙耳机怎么挑选?小编分享2023畅销蓝牙耳机排行榜

蓝牙耳机怎么挑选&#xff1f;蓝牙、音质、续航、佩戴是蓝牙耳机选购时最重要的四大维度&#xff0c;这几年随着技术的成熟体验有了很大改善&#xff0c;但挑选的时候仍然要仔细对比&#xff0c;不然容易踩雷。小编根据销量整理了蓝牙耳机排行榜&#xff0c;一起看看最受消费者…

水务行业数智化招标采购系统建设解决方案

水务行业数智化采购解决方案 国家“十四五”规划和2035年远景目标纲要&#xff1a;提升产业链供应链现代化水平。加快数字化发展&#xff0c;推动产业数字化&#xff0c;数字产业化&#xff0c;以数字化转型整体驱动生产方式、生活方式和治理方式变革。利用数字技术重构价值链…

kafka-Producer Sender 源码分析

说明 本文基于 kafka 2.7 编写。author blog.jellyfishmix.com / JellyfishMIX - githubLICENSE GPL-2.0 Sender 类属性 public class Sender implements Runnable {private final Logger log;/*** Sender 具体用的是 KafkaClient 接口的实现类 NetworkClient, 为 Sender 提…

【算法】经典背包问题

作者&#xff1a;指针不指南吗 专栏&#xff1a;算法篇 &#x1f43e;或许会很慢&#xff0c;但是不可以停下来&#x1f43e; 文章目录 引入Dp1.01背包2.完全背包3.多重背包4.分组背包 acwing 背包问题——学习笔记 01背包、完全背包、多重背包、分组背包 引入Dp Dp问题&#…

[SUCTF 2018]GetShell

有个文件上传&#xff0c;给了部分源码 if($contentsfile_get_contents($_FILES["file"]["tmp_name"])){$datasubstr($contents,5);foreach ($black_char as $b) {if (stripos($data, $b) ! false){die("illegal char");}} } 可以知道有…

黑白照片如何变彩色?黑白照变彩色的秘诀分享。​

黑白照片如何变彩色&#xff1f;将黑白照片变成彩色可以给照片增添生动的视觉效果和真实感&#xff0c;使得人物、场景更加具体形象&#xff0c;让人们更容易与之产生共鸣和情感联系&#xff0c;此外&#xff0c;通过给黑白老照片添加颜色&#xff0c;还可以打破时间和空间的限…

社区分享|JumpServer引领我走向开源天地

编者注&#xff1a;以下内容基于山东青岛的JumpServer社区用户JonnyJ的社区分享整理而成。 “接触到JumpServer之后&#xff0c;我从一个开源受益者逐渐成长为开源的贡献者。其实我们每个人都可以成为开源贡献者&#xff0c;不局限于软件产品&#xff0c;哪怕只是你的一段共享…

K8S集群+kubeadm+flannel+docker+harbor实例

目录 第一章.环境准备 1.1.部署架构图 1.2.节点要求 1.3.部署软件 1.4.修改主机名 1.5.所有节点修改hosts文件 1.6.关闭防火墙规则&#xff0c;关闭selinux&#xff0c;关闭swap交换 1.7.调整内核参数 第二章.部署K8S集群 2.1.所有节点安装docker 2.2.所有节点安装ku…

KVM管理-快照

KVM管理-快照 创建快照 为虚拟机vm1创建一个快照 [rootmyserver ~]# virsh snapshot-create-as vm1 vm1.snap Domain snapshot vm1.snap created快照只能使用qcow2创建&#xff0c;raw格式一般无法创建快照 查看磁盘镜像信息 [rootmyserver ~]# qemu-img info /var/lib/lib…

方案设计——食物测温仪方案

食物测温仪&#xff0c;在食物烹饪时&#xff0c;温度和时间至关重要&#xff0c;所以食物测温仪孕育而生&#xff0c;当用户使用时只需将食物测温仪的探头插入食物中&#xff0c;即刻能得到当前食物温度数据&#xff0c;不必用经验判断。做为一款食物测温仪&#xff0c;运用场…

Spring Boot :统一功能处理

在用户登陆验证的业务中&#xff0c;如果只是使用Spring AOP的话&#xff0c;session无法获取的&#xff0c;还有各种参数&#xff08;request等&#xff09;很难获取&#xff0c;这时候Spring拦截器就发挥了重大的作用了。 1.Spring 拦截器 创建拦截器分俩步&#xff1a;1.创…

项目集效益管理

项目集效益管理是定义、创建、最大化和交付项目集所提供的效益的绩效领域。 本章内容包括&#xff1a; 1 效益识别 2 效益分析和规划 3 效益交付 4 效益移交 5 效益维持 项目集效益管理包括一系列对项目集的成功极为重要的要素。项目集效益管理包括阐明项目集的 计划效益和预期…

AMBER分子动力学模拟之结果分析(最低能量结果)-- HIV蛋白酶-抑制剂复合物(3)

AMBER分子动力学模拟之结果分析(最低能量结果)-- HIV蛋白酶-抑制剂复合物(3) 在analysis目录下 解析.out文件 下载process_mdout.perl 脚本 perl process_mdout.perl ../md/md0.out ../md/md1.out ../md/md2.out # 可以不使用md0.out # 或者 $AMBERHOME/bin/process_md…

ShardingSphere 5.3 系列ShardingSphere-Proxy保姆级教程 | Spring Cloud 50

一、前言 通过以下系列章节&#xff1a; Spring Boot集成ShardingSphere实现数据分片&#xff08;一&#xff09; | Spring Cloud 40 Spring Boot集成ShardingSphere实现数据分片&#xff08;二&#xff09; | Spring Cloud 41 Spring Boot集成ShardingSphere实现数据分片&…

Linux:centos:组账户管理 》》添加组,用户加入组(设置组密码),删除组,查询账户信息,查询登录用户信息

/etc/group # 组信息文件 /etc/gshadow # 组密码文件&#xff08;不常用&#xff09; groupadd &#xff08;属性&#xff09; 组名 # 新建组 groupdel &#xff08;属性&#xff09; 组名 # 删除组 gpasswd # 可以…

Cartographer源码阅读---番外篇: Submap封装与维护

Cartographer中Submap(子图)没有被直接的调用进行维护, 而是针对2D和3D场景分别派生出子类Submap2D和Submap3D, 进行调用. 以2D为例, 为了方便维护, 又把Submap2D封装成了ActiveSubmaps2D进行维护, 其维护方式类似与滑窗, 也是只维护最近的一些数据. 1. Submap类 /*** brief …

Python学习之生成带logo背景图的二维码(静态和动态图)

前言 二维码简称 QR Code&#xff08;Quick Response Code&#xff09;&#xff0c;学名为快速响应矩阵码&#xff0c;是二维条码的一种&#xff0c;由日本的 Denso Wave 公司于 1994 年发明。现随着智能手机的普及&#xff0c;已广泛应用于平常生活中&#xff0c;例如商品信息…