C++派生类的构造函数

news2024/11/24 14:25:25

1.构造函数

定义了派生类之后,要使用派生类就需要声明该类的对象。对象在使用之前必须初始化。

派生类的成员对象是由所有基类的成员对象共同组成的。因此构造派生类函数的对象时,就要对基类的成员对象和新增的成员对象进行初始化。

基类的构造函数并没有继承下来,要完成这些工作,就必须给派生类添加新的构造函数。派生类对于基类的很多成员对象是不可以直接访问的,因此要完成对基类成员对象初始化工作,需要通过调用基类的构造函数。

派生类的构造函数需要以合适的初值作为参数,其中一些参数要传递给基类的构造函数,用于初始化相应的成员,另一些参数要用于对派生类新增的成员对象进行初始化。

在构造派生类对象时,会首先调用基类的构造函数,来初始化它们的数据成员,然后按照构造函数初始化列表中指定的方式初始化派生类新增的成员对象,最后才执行派生类构造函数的函数体。

(1)派生类构造函数的一般语法形式
派生类名::派生类名(参数表):基类名1(基类1初始化参数表),...,基类名n(基类n初始化参数表),成员对象名1(成员对象1初始化参数表),...,成员对象名m(成员对象m初始化参数表)
{
	派生类构造函数的其他初始化操作;
}

这里派生类的构造函数名于派生类名相同。在构造函数的参数表中,需要给出初始化基类数据和新增成员对象所需要的参数。在参数表之后,列出需要使用参数进行初始化的基类名和成员对象名及各自的初始化参数表,各项之间用逗号隔开。
当一个类同时有多个基类时,对于所有需要给予参数进行初始化的基类,都要显式给出基类名和参数表。对于使用默认构造函数的基类,可以不给出类名。同样,对于成员对象,如果是使用默认构造函数,也不需要写出对象名和参数表。

(2)声明派生类构造函数

如果对基类初始化时,需要调用基类的带有形参表的构造函数时,派生类就必须声明构造函数,提供一个将参数传递给基类构造函数的途径,保证基类进行初始化时能获得必要的数据。

如果不需要调用基类的带参数的构造函数,也不需要调用新增的成员对象的带参的构造函数,派生类也可以不用声明构造函数,全部采用默认的构造函数,这时新增成员的初始化工作可以用其他公有成员函数来完成。当派生类没有显式构造函数时,系统会隐含生成一个默认构造函数,该函数会使用基类的默认构造函数对继承自基类的数据初始化,并且调用派生类的类类型的成员对象的默认构造函数,对这些成员对象初始化。

派生类构造函数执行的一般顺序如下:
①调用基类的构造函数,调用顺序按照它们被继承时声明的顺序(从左到右)。
②对派生类新增的成员对象初始化,初始化顺序按照它在类中声明的顺序。
③执行派生类的构造函数体中的内容。

【注意】构造函数初始化列表中基类名、对象名之间的次序无关紧要,它们各自出现的顺序可以是任意的,无论它们的顺序怎样安排,基类构造函数的调用和各个成员对象的初始化顺序都是确定的。

【例】派生类的构造函数举例(多继承,含有内嵌对象),有3个基类B1,B2和B3。其中B3只有一个默认构造函数,其余两个基类的成员只有一个带有参数的构造函数。类D由这三个基类,结果公有继承派生而来。派生类新增了3个私有对象成员,分别是B1,B2和B3类的对象。

#include<iostream>
using namespace std;

class B1//基类B1,构造函数有参数
{
public:
	B1(int i)
	{
		cout << "构造B1对象" << i << endl;
	}
};

class B2//基类B2,构造函数有参数
{
public:
	B2(int j)
	{
		cout << "构造B2对象" << j << endl;
	}
};

class B3//基类B3,构造函数无参数
{
public:
	B3()
	{
		cout << "构造B3对象" << endl;
	}
};

class D:public B2,public B1,public B3//派生类D,注意基类名的顺序
{
public://派生类的公有成员
	D(int a,int b,int c,int d):B1(a),b2(d),b1(c),B2(b){}//注意类名的个数与顺序,注意成员对象名的个数与顺序

private://派生类的私有成员对象
	B1 b1;
	B2 b2;
	B3 b3;
};

int main()
{
	D d(1, 2, 3, 4);
	return 0;
}

运行结果:
在这里插入图片描述
结果分析:
因为**基类和内嵌对象成员都具有默认构造函数,所以派生类中需要显式声明一个构造函数用来初始化基类及内嵌对象成员。**派生类的构造函数定义为:

D(int a,int b,int c,int d):B1(a),b2(d),b1(c),B2(b){}

构造函数的参数表中给出了基类及内嵌对象成员所需要的全部参数,在冒号之后,分别列出各个基类及内嵌对象名和各自的参数。需要注意两个问题:一是,这里并没有列出全部基类和成员对象,由于B3类只有默认构造函数,不需要给它传递参数,因此,基类B3以及B3类成员对象b3就不必列出。二是,在派生类的构造函数中基类名和成员对象名的顺序是随意的。 这个派生类构造函数的函数体为空,只起到了传递参数和调用基类及内嵌对象构造函数的作用。

程序中主函数中只声明了一个派生类D的对象d,生成对象d时调用了派生类的构造函数。D类派生类构造函数的执行情况,应该是先调用基类的构造函数,然后调用内嵌成员对象的构造函数。基类构造函数的调用顺序是按照派生类定义时的顺序,因此应该是先B2,再B1,最后B3;而内嵌对象的构造函数调用顺序应该是按照成员在类中的声明顺序,应该是先B1,再B2,最后B3。

派生类构造函数的定义中,并没有显式列出基类B3和B3类的对象b3,这时系统就会自动调用该类的默认构造函数。如果一个基类同时声明了默认构造函数和带参数的构造函数,那么在派生类构造函数声明中,既可以显式列出基类名和相应的参数,也可以不列出。

(3)派生类构造函数的特点

①基类和内嵌对象成员都具有非默认构造函数时,派生类中需要显式声明一个构造函数用来初始化基类及内嵌对象成员。

②如果一个基类中只有默认构造函数,那么在派生类的构造函数中不需要列出这个基类和这个基类类型的成员对象,不需要它们传参。系统就会自动调用该类的默认构造函数。

③在派生类的构造函数中基类名和成员对象名的顺序是随意的。

④如果派生类构造函数的函数体为空,那么该派生类的构造函数只起到了传递参数和调用基类及内嵌对象构造函数的作用。

⑤类派生类构造函数的执行情况,应该是先调用基类的构造函数,然后调用内嵌成员对象的构造函数。基类构造函数的调用顺序是按照派生类定义时的顺序,内嵌对象的构造函数调用顺序应该是按照成员在类中的声明顺序。

⑥如果一个基类同时声明了默认构造函数和带参数的构造函数,那么在派生类构造函数声明中,既可以显式列出基类名和相应的参数,也可以不列出。

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

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

相关文章

负载均衡–HAProxy安装及搭建tidb数据库负载服务

作为一名开发人员&#xff0c;随着经验的增加和技术的沉淀&#xff0c;需要提高自己架构方面的知识&#xff0c;同时对于一个企业来说&#xff0c;搭建一套高可用、高性能的技术架构&#xff0c;对于公司的业务开展和提高服务的性能也是大有裨益的。本文重点从软件安装和搭建ti…

数字体验监控 (DEM)解决方案

数字体验监控 &#xff08;DEM&#xff09; 是监控 Web 应用程序的前端和后端以确保无缝交付和最佳性能的过程&#xff0c;DEM 提供对业务应用程序可用性的洞察&#xff0c;可以对其进行分析以改善用户体验。 为什么数字体验监控很重要 在未确保最佳性能和适当行为的情况下向…

python实现对图油画、卡通、梦幻、草图、水彩效果

本篇博客将介绍如何使用wxPython模块和OpenCV库来实现对图像进行灰度化、二值化、伽马校正、色彩空间转换和图像反转这5种效果的合并程序。程序可以通过wxPython提供的GUI界面来选择图片路径和效果类型&#xff0c;程序会将处理后的图像保存到指定路径并打开。 步骤一&#xf…

W5500-EVB-PICO作为TCP Client 进行数据回环测试(五)

前言 上一章我们用W5500-EVB-PICO开发板通过DNS解析www.baidu.com&#xff08;百度域名&#xff09;成功得到其IP地址&#xff0c;那么本章我们将用我们的开发板作为客户端去连接服务器&#xff0c;并做数据回环测试&#xff1a;收到服务器发送的数据&#xff0c;并回传给服务器…

《吐血整理》高级系列教程-吃透Fiddler抓包教程(37)-掌握Fiddler中Fiddler Script用法你有多牛逼-下

1.简介 Fiddler是一款强大的HTTP抓包工具&#xff0c;它能记录所有客户端和服务器的http和https请求&#xff0c;允许你监视&#xff0c;设置断点&#xff0c;甚至修改输入输出数据. 使用Fiddler无论对开发还是测试来说&#xff0c;都有很大的帮助。Fiddler提供的功能基本上能…

在线高精地图生成算法调研

1.HDMapNet 整体的网络架构如图所示&#xff0c;最终的Decoder输出三个分支&#xff0c;一个语义分割&#xff0c;一个embedding嵌入分支&#xff0c;一个方向预测。然后通过后处理将这些信息处理成向量化的道路表示。 img2bev的方式之前有IPM&#xff0c;通过假设地面的高度都…

模仿火星科技 基于cesium+水平面积测量+可编辑

​ 当您进入Cesium的编辑水平积测量世界&#xff0c;下面是一个详细的操作过程&#xff0c;帮助您顺利使用这些功能&#xff1a; 1. 创建提示窗&#xff1a; 启动Cesium应用&#xff0c;地图场景将打开&#xff0c;欢迎您进入编辑模式。 在屏幕的一角&#xff0c;一个友好的提…

Linux6.34 Kubernetes yaml文件详解

文章目录 计算机系统5G云计算第三章 LINUX Kubernetes yaml文件详解一、yaml文件概述1.查看 api 资源版本标签2.写一个yaml文件demo 计算机系统 5G云计算 第三章 LINUX Kubernetes yaml文件详解 一、yaml文件概述 Kubernetes 支持 YAML 和 JSON 格式管理资源对象 JSON 格式…

ArcGIS Pro基础:【划分】工具实现等比例、等面积、等宽度划分图形操作

本次介绍【划分】工具的使用&#xff0c;如下所示&#xff0c;为该工具所处位置。使用该工具可以实现对某个图斑的等比例面积划分、相等面积划分和相等宽度划分。 【等比例面积】&#xff1a;其操作如下所示&#xff0c;其中&#xff1a; 1表示先选中待处理的图斑&#xff0c;2…

利用GPT打造你的博客|论文的专属讲解员→强制让GPT学习你的知识?(不需要魔法)

文章目录 1 前言2 搭建我的博客问答系统2.1 平台介绍&#xff08;不需要魔法即可访问&#xff09;2.2 前期准备2.3 上传博客作为数据集至Dify2.4 搭建你的博客回答专员 3 利用有针对性的GPT帮助我们阅读前沿论文4 结语 个人博客专属问答员&#xff1a;demo 1 前言 GPT是生成式…

React入门学习笔记3

事件处理 通过onXxx属性指定事件处理函数(注意大小写) React使用的是自定义(合成)事件, 而不是使用的原生DOM事件——为了更好的兼容性 eg&#xff1a;οnclick》onClickReact中的事件是通过事件委托方式处理的(委托给组件最外层的元素)——为了更高效通过event.target得到发生…

Go context.WithCancel()的使用

WithCancel可以将一个Context包装为cancelCtx,并提供一个取消函数,调用这个取消函数,可以Cancel对应的Context Go语言context包-cancelCtx 疑问 context.WithCancel()取消机制的理解 父母5s钟后出门&#xff0c;倒计时&#xff0c;父母在时要学习&#xff0c;父母一走就可以玩 …

视频怎么改成gif格式?简单几步就可以轻松视频转gif

平时我们使用的许多gif图片&#xff0c;其实都是视频片段&#xff0c;那么是怎么把视频转gif格式的呢&#xff1f;可以使用视频转gif工具来完成gif制作&#xff0c;下面就给大家分享一个简单的视频转gif在线制作&#xff08;https://www.gif.cn&#xff09;的方法&#xff0c;一…

pycharm离线安装依赖包

一、对于单个下载离线包&#xff0c;然后安装 1、先去https://pypi.org/网站下载离线包&#xff0c;下载到本地&#xff1b; 2、从磁盘中找到刚刚下载包&#xff0c;点击确定就可以安装了 二、将本地项目所有依赖包全部下载下来&#xff0c;然后批量在另一个项目&#xff…

Linux抓包工具----tcpdump

这是一个目录 一、什么是tcpdump二、为什么要用tcpdump三、tcpdump在哪里&#xff1f;四、怎么用tcpdump&#xff1f;4.1 命令格式4.2 常用选项4.2.1 对网络接口抓包 -i4.2.2 指定收取数据包的数量 -c4.2.3 不把ip转换成域名&#xff0c;直接显示ip -n4.2.4 显示ip和端口号 -nn…

权限校验—接口检验

一、背景介绍 最近项目中要实现根据不同用户去划分不同的角色&#xff0c;而不同角色具备调用不同接口的权限这个功能。用户在调用接口时需要校验用户是否具有权限访问接口&#xff0c;防止外界恶意调用随意篡改 二、思路&方案 为什么要进行接口鉴权&#xff1f; 接口鉴权…

几种常见的光纤接头有哪些?

名称: 光纤接头 光纤接头(optical fiber splice),将两根光纤永久地或可分离开地联结在一起,并有保护部件的接续部分,光纤接头是光纤的末端装置问题描述: 几种常见的光纤接头有哪些? 回答: 1.常见的光纤接头 LC 、SC 、FC 、ST、 MPO LC (Lucent connector) 小…

MySQL 事务原理:锁机制

文章目录 一、锁类型1.1 全局锁1.2 表级锁1.2.1 表锁1.2.2 元数据锁1.2.3 意向锁1.2.4 自增锁 1.3 行级锁1.3.1 记录锁1.3.2 间隙锁1.3.3 临键锁1.3.4 插入意向锁 1.4 锁的兼容性 二、锁的CUDP2.1 查询2.2 删除、更新2.3 插入 三、锁的对象四、并发死锁4.1 相反加锁顺序导致死锁…

监控Kafka的关键指标

Kafka 架构 上面绿色部分 PRODUCER&#xff08;生产者&#xff09;和下面紫色部分 CONSUMER&#xff08;消费者&#xff09;是业务程序&#xff0c;通常由研发人员埋点解决监控问题&#xff0c;如果是 Java 客户端也会暴露 JMX 指标。组件运维监控层面着重关注蓝色部分的 BROKE…

Redis 高频数据类型使用详解

目录 一、前言 二、Redis常用数据类型 2.1 常见的数据类型 三、String 类型 3.1 String 类型简介 3.2 String常用操作命令 3.2.1 String 操作命令实践 3.3 常用业务场景 3.3.1 session共享 3.3.2 登录失败计数器 3.3.3 限流 3.3.4 多线程安全控制 四、Hash类型 4…