C++派生类的构造函数

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.mzph.cn/news/25213.shtml

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

相关文章

RabbitMQ消息队列

目录 网址&#xff1a; 一、项目准备 1.导入依赖 2.抽取工具类 配置的属性在哪里呢 二、代码编写 1.简单模式 生产者 消费者 2.Work queues工作队列模式 生产者 消费者1 消费者2 3.Publish/Subscribe发布与订阅模式 生产者 消费者1 消费者2 4.Routing路由模式…

git【潦草学习】

初始配置git 查询版本号 初次使用git前配置用户名与邮箱地址 git config --global user.name "your name" git config --global user.email "your email" git config -l 发现最后两行多出了用户名和邮箱&#xff0c;说明配置成功

【雕爷学编程】Arduino动手做(184)---快餐盒盖,极低成本搭建机器人实验平台3

吃完快餐粥&#xff0c;除了粥的味道不错之外&#xff0c;我对个快餐盒的圆盖子产生了兴趣&#xff0c;能否做个极低成本的简易机器人呢&#xff1f;也许只需要二十元左右 知识点&#xff1a;轮子&#xff08;wheel&#xff09; 中国词语。是用不同材料制成的圆形滚动物体。简…

解决Map修改key的问题

需求 现在返回json数据带有分页的数据&#xff0c;将返回data属性数据变更为content&#xff0c;数据不变&#xff0c;key发生变化 实现1&#xff0c;源数据比较复杂&#xff0c;组装数据比较麻烦 说明&#xff1a;如果使用这种方式完成需求&#xff0c;需要创建对象&#xff0…

VLAN原理+配置

目录 一&#xff0c; 以太网二层交换机 二&#xff0c;三层架构&#xff1a; 三&#xff0c;VLAN配置思路 1.创建vlan 2.接口划入vlan 3.trunk干道 4.vlan间路由器 5.DHCP池塘配置 四&#xff0c;华为VLAN部分的接口模式讲解&#xff1a; 五&#xff0c;华为VLAN部分的…

mysql二进制方式升级8.0.34

一、概述 mysql8.0.33 存在如下高危漏洞&#xff0c;需要通过升级版本修复漏洞 Oracle MySQL Cluster 安全漏洞(CVE-2023-0361) mysql/8.0.33 Apache Skywalking <8.3 SQL注入漏洞 二、查看mysql版本及安装包信息 [rootlocalhost mysql]# mysql -V mysql Ver 8.0.33 fo…

Eureka增加账号密码认证登录

一、业务背景 注册中心Eureka在微服务开发中经常使用到&#xff0c;用来管理发布的微服务&#xff0c;供前端或者外部调用。但是如果放到生产环境&#xff0c;我们直接通过URL访问的话&#xff0c;这显然是不安全的。 所以需要给注册中心加上登录认证。 通过账号和密码认证进行…

【计算机网络】socket编程

文章目录 1. 网络通信的理解2.进程PID可以取代端口号吗&#xff1f;3. 认识TCP协议4. 认识 UDP协议5. socket编程接口udp_server.hpp的代码解析socket——创建 socket 文件描述符Initserver——初始化1.创建套接字接口&#xff0c;打开网络文件bind——绑定的使用 2.给服务器指…

[webpack] 基本配置 (一)

文章目录 1.基本介绍2.功能介绍3.简单使用3.1 文件目录和内容3.2 下载依赖3.3 启动webpack 4.基本配置4.1 五大核心概念4.2 基本使用 1.基本介绍 Webpack 是一个静态资源打包工具。它会以一个或多个文件作为打包的入口, 将我们整个项目所有文件编译组合成一个或多个文件输出出去…

webpack基础知识八:说说如何借助webpack来优化前端性能?

一、背景 随着前端的项目逐渐扩大&#xff0c;必然会带来的一个问题就是性能 尤其在大型复杂的项目中&#xff0c;前端业务可能因为一个小小的数据依赖&#xff0c;导致整个页面卡顿甚至奔溃 一般项目在完成后&#xff0c;会通过webpack进行打包&#xff0c;利用webpack对前…

医疗器械研发中的可用性工程实践(一)

致读者&#xff1a;以前看《楚门的世界》&#xff0c;《蝴蝶效应》&#xff0c;《肖申克的救赎》&#xff0c;《教父》&#xff0c;《横道世之介》&#xff0c;《老友记》&#xff0c;一个人的一生匆匆。作为平凡人就是历史大河中的浪花&#xff0c;顺势而为&#xff0c;起起伏…

算法与数据结构(二十一)二叉树(纲领篇)

备注&#xff1a;本文旨在通过 labuladong 的二叉树&#xff08;纲领篇&#xff09;理解框架思维&#xff0c;用于个人笔记及交流学习&#xff0c;版权归原作者 labuladong 所有&#xff1b; 我刷了这么多年题&#xff0c;浓缩出二叉树算法的一个总纲放在这里&#xff0c;也许…

ELK企业级日志分析系统

目录 一、ELK 概述 1.ElasticSearch 2.Kiabana 3.Logstash 可以添加的其它组件 1.Filebeat 2.Fluentd 三、为什么要使用 ELK 四、ELK 的工作原理 五、 ELK Elasticsearch 集群部署 更改主机名、配置域名解析、查看Java环境 部署 Elasticsearch 软件 修改elasticsearc…

爬虫获取电影数据----以沈腾参演电影为例

数据可视化&分析实战 1.1 沈腾参演电影数据获取 文章目录 数据可视化&分析实战前言1. 网页分析2. 构建数据获取函数2.1 网页数据获取函数2.2 网页照片获取函数 3. 获取参演影视作品基本数据4. 电影详细数据获取4.1 导演、演员、描述、类型、投票人数、评分信息、电影海…

Wisej.NET Crack,Wisej.NET的核心功能

Wisej.NET Crack&#xff0c;Wisej.NET的核心功能 Wisej.NET是一个跨平台的web框架&#xff0c;用于使用.NET和C#/VB.NET而不是HTML和JavaScript构建现代HTML5应用程序。它包含创建任务关键型web应用程序所需的一切&#xff0c;包括UI组件、会话处理、状态管理和后端集成。借助…

单元测试之 - Spring框架提供的单元/集成测试注解

Spring框架提供了很多注解来辅助完成单元测试和集成测试(备注&#xff1a;这里的集成测试指容器内部的集成测试&#xff0c;非系统间的集成测试)&#xff0c;先看看Spring框架提供了哪些注解以及对应的作用。RunWith(SpringRunner.class) / ExtendWith(SpringExtension.class)&…

设计模式行为型——备忘录模式

目录 什么是备忘录模式 备忘录模式的实现 备忘录模式角色 备忘录模式类图 备忘录模式举例 备忘录模式代码实现 备忘录模式的特点 优点 缺点 使用场景 注意事项 实际应用 什么是备忘录模式 备忘录模式&#xff08;Memento Pattern&#xff09;又叫做快照模式&#x…

高并发负载均衡---LVS

目录 前言 一&#xff1a;负载均衡概述 二&#xff1a;为啥负载均衡服务器这么快呢&#xff1f; ​编辑 2.1 七层应用程序慢的原因 2.2 四层负载均衡器LVS快的原因 三&#xff1a;LVS负载均衡器的三种模式 3.1 NAT模式 3.1.1 什么是NAT模式 3.1.2 NAT模式实现LVS的缺点…

openwr折腾记7-Frpc使用自主域名解析透传本地服务免费不断线的探索

Frpc使用自主域名解析透传本地服务 综述frp透传http服务结构流程 第一部分openwrt-frpc客户端配置和使用指定服务器指定规则在自己的域名运营商处添加域名解析 第二部分shell编码实现frp自由切换服务器并更新dns解析获取切换服务器参数脚本实现切换脚本更新DNS解析打开openwrt计…

MySQL — InnoDB事务

文章目录 事务定义事务特性事务隔离级别READ UNCOMMITTEDREPEATABLE READREAD COMMITTEDSERIALIZABLE 事务存在的问题脏读&#xff08;Dirty Read&#xff09;不可重复读&#xff08;Non-repeatable Read&#xff09;幻读&#xff08;Phantom Read&#xff09; 事务定义 数据库…