【C++】构造函数和析构函数第三部分(各种构造函数调用规则、多个对象的构造和析构、初始化列表)--- 2023.11.6

news2024/11/23 18:54:45

目录

      • 各种构造函数的调用规则
        • 对象以值的方式给函数参数
        • 用一个已有的对象去初始化另一个对象
        • 函数的局部对象以值的方式从函数返回
        • 调用规则1
        • 调用规则2
      • 多个对象的构造和析构
      • 初始化列表
      • 结束语

各种构造函数的调用规则

对象以值的方式给函数参数

实例:

class Maker
{
public:
	Maker()
	{
		cout << "无参构造函数" << endl;
	}
	Maker(int a)
	{
		cout << "有参构造函数" << endl;
	}
	Maker(const Maker &maker)
	{
		cout << "拷贝构造函数" << endl;
	}
	~Maker()
	{
		cout << "析构函数" << endl;
	}
};

void func(Maker m)
{

}

void test01()
{
	Maker m1;
	func(m1);

}

对上述代码进行分析:

Maker m1;

实例化对象,并且该对象名为m1,在实例化对象过程中会调用Maker类中的无参构造。

func(m1);

该func函数中的形参为Maker m,并且传入该函数的形参为刚刚实例化完成的对象m1,所以实际上为Maker m = m1。即会调用Maker类中的拷贝构造函数。

最后在完成该函数生命周期时,会相反顺序依次调用析构函数来完成释放。

代码运行结果如下:

在这里插入图片描述

用一个已有的对象去初始化另一个对象

实例:

void test02()
{
	Maker m1;
	Maker m2(m1);
}

对上述代码进行分析:

Maker m1;

实例化对象,并且该对象名为m1,在实例化对象过程中会调用Maker类中的无参构造。

Maker m2(m1);

相当于调用Maker类中的拷贝构造函数。

代码运行结果如下:
在这里插入图片描述

函数的局部对象以值的方式从函数返回

实例:

Maker func2()
{
	//局部对象
	Maker m;
	cout << "局部对象的地址:" << &m << endl;

	return m;
}

void test03()
{
	
	Maker m1 = func2();

	cout << "m1对象的地址:" << &m1 << endl;
}

对上述代码进行分析:

func2函数的主要作用为将实例化成功的对象m的地址打印出来,并且将该对象作为该函数的返回值。

Maker m1 = func2();

将func2()的函数的返回值传递给m1,并且打印m1的地址。理论上m1和m的地址是一样的。

代码运行结果如下:
在这里插入图片描述

调用规则1

如果程序员提供了有参构造,那么编译器不会提供默认构造函数,但是会提供默认的拷贝构造

实例:

class Maker
{
public:
	Maker()
	{
		cout << "无参构造函数" << endl;
	}
	Maker(int a)
	{
		cout << "有参构造函数" << endl;
	}
	~Maker()
	{
		cout << "析构函数" << endl;
	}
};

void test01()
{

	Maker m(10);
	Maker m2(m);
}

对上述代码进行分析:

Maker m(10);

调用Maker类中的有参构造函数,即a = 10

Maker m2(m);

使用该函数将会调用拷贝构造函数,但是我们发现在Maker类中并没有创建拷贝构造函数,我们先试试看程序能不能正常运行?

代码运行结果如下:
在这里插入图片描述
由上述可知,代码可以正常运行,并没有报错,这是因为编译器会提供默认的拷贝构造函数,只不过这个拷贝构造函数不做任何处理。

调用规则2

如果程序员提供了拷贝构造函数,那么编译器不会提供默认的构造函数和默认的拷贝构造函数

实例:

class Maker
{
public:

	Maker(const Maker& maker)
	{
		cout << "拷贝构造函数" << endl;
	}
	~Maker()
	{
		cout << "析构函数" << endl;
	}
};

void test02()
{
	Maker m;
}

对上述代码进行分析:

Maker m;

实例化对象m时,会自动调用构造函数,但是我们发现在Maker类中创建了拷贝构造函数,我们先试试看代码能不能正常运行?

代码运行结果如下:

在这里插入图片描述
从上可知,代码并不能正常运行,即我们可以得知,当提供了拷贝构造函数,那么编译器不会提供默认的构造函数和默认的拷贝构造函数。

多个对象的构造和析构

实例:

class BMW
{
public:
	BMW()
	{
		cout << "BMW构造" << endl;
	}

	~BMW()
	{
		cout << "BMW析构" << endl;
	}
};

class Buick
{
public:
	Buick()
	{
		cout << "Buick构造" << endl;
	}

	~Buick()
	{
		cout << "Buick析构" << endl;
	}
};

class Maker
{
public:
	Maker()
	{
		cout << "Maker构造" << endl;
	}

	~Maker()
	{
		cout << "Maker析构" << endl;
	}
private:
	
	Buick bui;//成员对象
	BMW bmw;//成员对象
};

void test01()
{
	Maker m;
}

对上述代码进行分析:

private:
	
	Buick bui;
	BMW bmw;

在之前的实例中,我们一般私有化的时变量,并没有对对象进行私有化,但是实际上在C++中这个是可以私有化的,并且我们将该对象称为成员对象。

接下来我们先看看代码效果是什么样子的?

在这里插入图片描述

如上所示,首先会调用Buick构造函数,然后紧接着是BMW构造函数,最后才是Maker构造函数,细心的我们会发现如果类有成员对象,那么先调用成员对象的构造函数,再调用本身的构造函数,析构函数的调用顺序反之。

那么此时我们如果将Buick和BMW的顺序互换一下,代码运行效果会是什么呢?

代码运行结果如下:

在这里插入图片描述
并且还需要注意一点:

如果有成员对象,那么实例化对象时,必须保证成员对象的构造和析构能被调用

初始化列表

实例:

class BMW2
{
public:

	BMW2(int a)
	{
		cout << "BMW2有参构造" << a << endl;
	}

	~BMW2()
	{
		cout << "BMW2析构" << endl;
	}
};

class Buick2
{
public:
	Buick2()
	{
		cout << "Buick2构造" << endl;
	}

	~Buick2()
	{
		cout << "Buick2析构" << endl;
	}
};

class Maker2
{
public:

	Maker2() :bmw(10)
	{
		cout << "Maker2构造" << endl;
	}


	~Maker2()
	{
		cout << "Maker2析构" << endl;
	}
private:

	Buick2 bui;//成员对象
	BMW2 bmw;//成员对象
};

void test02()
{
	Maker2 m;
}

int main()
{
	test02();
}

对上述代码进行分析:

Maker2() :bmw(10)
	{
		cout << "Maker2构造" << endl;
	}

当调用Maker2的构造函数时,会调用成员对象bmw的有参构造函数,并将10赋值给a。

代码运行结果如下:

在这里插入图片描述
那此时有多个对象需要指定调用某个构造函数,我们需要用逗号隔开。

实例如下:

class BMW2
{
public:

	BMW2(int a)
	{
		cout << "BMW2有参构造" << a << endl;
	}

	~BMW2()
	{
		cout << "BMW2析构" << endl;
	}
};

class Buick2
{
public:
	Buick2(int b, int c)
	{
		cout << "Buick2构造" << endl;
	}

	~Buick2()
	{
		cout << "Buick2析构" << endl;
	}
};

class Maker2
{
public:

	Maker2(int a, int b, int c) :bmw(a), bui(b, c)
	{
		cout << "Maker2构造" << endl;
	}


	~Maker2()
	{
		cout << "Maker2析构" << endl;
	}
private:

	Buick2 bui;//成员对象
	BMW2 bmw;//成员对象
};

void test02()
{
	Maker2 m(30, 10, 20);
}

int main()
{
	test02();
}

对上述代码进行分析:

Maker2(int a, int b, int c) :bmw(a), bui(b, c)
{
	cout << "Maker2构造" << endl;
}

当使用Maker2进行实例化对象为m时,需要使用有参构造函数,将30,10,20这三个值分别传给bmw和bui对象,并且中间用逗号隔开。

代码运行结果如下:

在这里插入图片描述

除了以上几点,还有几点需要我们注意:

  1. 初始化列表是干什么用的,指定调用成员对象的某个构造函数
  2. 初始化列表只能写在构造函数
  3. 如果使用了初始化列表,那么所有的构造函数都要写初始化列表
  4. 可以使用对象的构造函数传递数值给成员对象的变量

结束语

如果觉得这篇文章还不错的话,记得点赞 ,支持下!!!

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

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

相关文章

思维模型 布里丹毛驴效应

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。犹豫不决是病&#xff0c;得治&#xff5e; 1 布里丹毛驴效应的应用 1.1 犹豫不决的产品“施乐 914” 20 世纪 60 年代&#xff0c;美国一家名为施乐&#xff08;Xerox&#xff09;的公司…

如何在CPU上进行高效大语言模型推理

大语言模型&#xff08;LLMs&#xff09;已经在广泛的任务中展示出了令人瞩目的表现和巨大的发展潜力。然而&#xff0c;由于这些模型的参数量异常庞大&#xff0c;使得它们的部署变得相当具有挑战性&#xff0c;这不仅需要有足够大的内存空间&#xff0c;还需要有高速的内存传…

5+单细胞+铜死亡+实验,干湿结合生信思路,有条件做实验的可模仿

今天给同学们分享一篇生信文章“Single-cell transcriptomics reveals immune infiltrate in sepsis”&#xff0c;这篇文章发表在Front Pharmacol期刊上&#xff0c;影响因子为5.6。 结果解读 作者研究的流程图 作者首先制定了这项研究的总体技术路线&#xff0c;如图1所示。…

UVM源码--uvm_component 浅析(一)

目录 1. uvm_object 2. uvm_component 3. 为什么在uvm_component 例化是需要指定一个parent&#xff1f; 4.uvm_component 的树形结构是如何组织起来的&#xff1f; 5. 静态函数与非静态函数的区别&#xff1a; 6. uvm_root 的单实例实现思路&#xff1a; 7. run_test 的…

动态头:用注意力统一目标检测头

目标检测是回答计算机视觉应用中“哪些目标位于哪里”的问题。在深度学习时代&#xff0c;几乎所有现代目标检测器共享相同的范式——特征提取的主干和定位和分类任务的头部。如何提高目标检测头的性能已经成为现有目标检测工作中的一个关键问题。检测头应该是尺度感知&#xf…

modelscope适配昇腾NPU

注意 我只做了raner,raner-50cls,corom这三个模型的适配&#xff0c;不能保证其他模型同样好使。 我的环境信息 NPU: Atlas 300I Pro Modelsope: 1.9.4&#xff08;最好要使用这个版本呀&#xff0c;因为后面要改一下源码&#xff09; python: 3.8 torch: 2.0.1 内核以…

深度学习之基于YoloV5交通信号标志识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 基于YoloV5交通信号标志识别系统介绍 基于YoloV5的交通信号标志识别系统是一种深度学习应用&#xff0c;旨在通过使…

《国产服务器操作系统发展报告(2023)》重磅发布

11月1日&#xff0c;《国产服务器操作系统发展报告&#xff08;2023&#xff09;》&#xff08;以下简称“报告”&#xff09;在 2023 云栖大会上正式发布&#xff0c;开放原子开源基金会理事长孙文龙、中国信息通信研究院副总工程师石友康、阿里云基础软件部副总裁马涛、浪潮信…

明御安全网关任意文件上传漏洞复现

简介 安恒信息明御安全网关(NGFW) 秉持安全可视、简单有效的理念&#xff0c;以资产为视角的全流程防御的下一代安全防护体系&#xff0c;并融合传统防火墙、入侵防御系统、防病毒网关、上网行为管控、VPN网关、威胁情报等安全模块于一体的智慧化安全网关。 较低版本的系统存…

享搭低代码平台:快速构建符合需求的会议室管理系统应用

本文介绍了享搭低代码平台如何赋予用户快速构建会议室管理系统应用的能力。通过在应用商店安装费用会议室管理模板&#xff0c;并通过拖拽方式对模板进行自定义扩充&#xff0c;用户可以快速搭建符合自身需求的会议室管理系统&#xff0c;从而提高会议室预订和管理的效率。 介绍…

华为eNSP实验-三层交换机的不同网段通信(通过OSPF路由方式)

1.拓扑图 2.过程如下 2.1 首先PC1和PC2配置好IP地址 2.2 在SW1上配置虚拟网关及VLAN <Huawei>system-view [Huawei]sysname SW1 [SW1]undo info-center enable [SW1] [SW1]vlan batch 10 20 [SW1]interface GigabitEthernet 0/0/1 [SW1-GigabitEthernet0/0/1]port li…

maven项目子类项目版本与父类版本不一致

项目的依赖关系 A项目的父pom是spring boot&#xff0c;A依赖pom B&#xff0c;B依赖hibernate B引用的hibernate版本为8.0.1 A引用的hibernate版本为6.2.0 maven helper插件显示无依赖冲突 这就很奇怪&#xff0c;为何依赖版本有问题呢&#xff1f;是在看不出来问题&#xff…

在线实用计算工具大全

在线实用计算工具大全 在线计算工具的实用&#xff0c;可以有效提高学习或工作效率&#xff0c;本博文介绍一个在线的实用计算工具大全&#xff08;https://tool.520101.com&#xff09;&#xff0c;作为一种辅助学习工具。 1. 在线排列组合计算 https://tool.520101.com/cal…

JS定时器实现页面N秒后跳转 实现每隔 1s 自动刷新页面并格式化的显示当前时间

1. 通过 setInterval 函数&#xff0c;来周期性的更新倒计时间&#xff0c;同时更新到页面。即通过设置页面可以显示 3 2 1&#xff0c;然后跳转。1000指的是每隔1秒执行一次。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF…

LightDB23.4 GBK和UTF8转码失败的字符替换成空格

背景介绍 用户使用迁移工具从Oracle数据库迁移数据到LightDB的过程中发现&#xff0c;某些GBK编码转成UTF8编码后&#xff0c;在插入到LightDB中会报错。以GBK编码AAA1为例&#xff0c;LightDB的GBK和UTF8映射表中不支持AAA1这个GBK编码的转换。不支持的GBK编码都是处于GBK编码…

ifream标签中的子页面,操作父页面的元素

问题描述&#xff1a;子页面内容发生变化时&#xff0c;导航栏不会跟切换 解决办法&#xff1a; window.parent.document.getElementById demo html1 <html> <head><meta charset"UTF-8"><!-- import CSS --><link rel"stylesh…

使用VSCODE链接Anaconda

打代码还是在VSCODE里得劲 所以得想个办法在VSCODE里运行py文件 一开始在插件商店寻找插件 但是没有发现什么有效果的 幸运的是VSCODE支持自己选择Python的编译器 打开VSCODE 按住CtrlShiftP 输入Select Interpreter 如果电脑已经安装上了Python的环境 VSCODE会默认选择普通…

R语言实操记录——导出高清图片(矢量图)

R语言 R语言实操记录——导出高清图片&#xff08;矢量图&#xff09; 文章目录 R语言一、起因&#xff08;废话&#xff0c;可跳过&#xff09;二、如何在R中导出高清图片&#xff08;矢量图&#xff09;2.1、保存为EPS图片格式后转AI编辑2.2、保存为PDF格式&#xff08;推荐…

在直播系统中使用SRT协议传输视频

目录 1、简述 2、NDI、RTSP协议的优缺点 3、SRT协议简介 4、SRT协议链接地址URL格式 &#xff08;1&#xff09;listener&#xff1a; &#xff08;2&#xff09;caller&#xff1a; 5、手机发送SRT实时音视频 6、OBS中的设置 7、在vMix中的设置 8、写在最后 1、简述 …

财报解读:抢滩“睡眠经济”,麒盛科技如何制胜市场?

现代市场经济理论的鼻祖亚当斯密曾说&#xff0c;有需求就有市场&#xff0c;有市场才有发展。 调查研究显示&#xff0c;我国超3亿人存在睡眠障碍&#xff0c;其中超3/4的人晚11点以后入睡&#xff0c;近1/3的人熬到凌晨1点以后才能入睡。针对“睡个好觉”需求的“睡眠经济”…