C++ 类的继承与派生

1.继承关系举例

交通工具的分类如下图所示:
在这里插入图片描述
这个分类树反映了交通工具的派生关系,最高层是抽象程度最高的,是最具有普遍和一般意义的概念,下层具有了上层的特性,同时加入了自己的新特征,而最下层是最为具体的。这个层次结构中,由上到下,是一个具体化、特殊化的过程;由下到上,是一个抽象化的过程。上下层之间的关系就可以看作是基类与派生类的关系。

所谓继承就是从先辈处得到属性和行为特征。类的继承,就是新的类从已有类那里得到已有的特性。 从另一个角度来看这个问题,从已有类产生新类的过程就是类的派生。 类的继承与派生机制允许程序员在保持原有类特性的基础上,进行更具体、更详细的修改和扩充。由原有的类产生新类时,新类便包含了原有类的特征,同时也可以加入自己所特有的新特性。原有的类称为基类或父类产生的新类称为派生类或子类。 派生类同样也可以作为基类派生新的类,这样就形成了类的层次结构。类的派生实际上是一种演化、发展过程,即通过扩展、更改和特殊化,从一个已知类出发建立一个新类。通过类的派生可以建立具有共同关键特征的对象家族,从而实现代码的重用,这种继承和派生的机制对于已有程序的发展和改进非常有利。

2.派生类的定义

(1)派生类的一般定义语法

在C++中,派生类的一般定义语法为:

class 派生类名::继承方式 基类名1,继承方式 基类名2,...,继承方式 基类名n
{派生类成员声明;
};

例如,假设基类B1和B2是已经定义的类,下面的语句定义了一个名为D的派生类,该类从基类B1和B2派生而来:

class D::public B1,private B2
{public:D();~D();
};

定义中的“基类名”(如B1和B2)是已有的类的名称,“派生类名”是继承原有类的特性而生成的新类的名称(如D)。

(2)多继承和单继承

一个派生类,可以同时有多个基类,这种情况称为多继承,这时的派生类同时得到了多个已有类的特征。上述例子就是一个多继承实例。一个派生类只有一个直接基类的情况,称为单继承。单继承可以看作是多继承的一个最简单的特例,多继承可以看作是多个单继承的组合,它们之间的很多特性是相同的。两种继承的UML表示如图所示:

在这里插入图片描述
(3)直接基类和间接基类

在派生过程中,派生出来的新类也同样可以作为基类再继续派生新的类,此外,一个基类可以同时派生处多个派生类,也就是说,一个类从父类继承来的特征也可以被其他新的类所继承,一个父类的特征,可以同时被多个子类继承。这样,就形成了一个相互关联的类的家族,有时也称作类族。在类族中,直接参与派生出某类的基类称为直接基类基类的基类甚至更高层的基类称为间接基类。比如由“交通工具”类派生出“汽车”类,“汽车”类又派生出“卡车”类,则“汽车”类是“卡车”类的直接基类,“交通工具”类是“汽车”类的直接基类,而“交通工具”类是“卡车”类的间接基类。

(4)继承方式
在派生类的定义中,除了要指定基类外,还需要指定继承方式。继承方式规定了如何访问从基类继承的成员。。在派生类的定义语句中,每一个“继承方式”,只限定紧随其后的基类。继承方式关键字为:public,protected和private,分别表示公有继承。保护继承和私有继承。如果不显式地给出继承方式关键字,系统的默认值就认为是私有继承(private)。类的继承方式指定了派生类成员以及类外对象对于从基类继承来的成员的访问权限。在下面这个例子中:

class D::public B1,private B2
{public:D();~D();
};

对B1是公有继承,对B2是私有继承,同时声明了派生类自己新的构造函数和析构函数。

(5)派生类成员

派生类成员是指除了从基类继承来的所有成员之外,新增加的数据和函数成员。 这些新增的成员,正是派生类不同于基类的关键所在,是派生类对基类的发展。当重用和扩充已有的代码时,就是通过在派生类中新增成员来添加新的属性和功能。

3.派生类生成过程

在C++程序设计中,进行派生类的定义之后,给出该类的成员函数的实现,整个类就算完成了,可以由它来生成对象进行实际问题的处理。

派生新类,实际经历了3个步骤:吸收基类成员,改造基类成员、添加基类成员。

面向对象的继承和派生机制,其最主要目的是实现代码的重用与扩充。因此吸收基类成员就是一个重用的过程,而对基类成员进行调整、改造以及添加新成员就是原有代码的扩充过程,二者是相辅相成的。

基类A和派生类B的定义如下:

class A
{
private:string i;double b;static int t;
protected:A();void r();void e()const;
public:const string &gi()const{}double gb()const{}static double gt(){}void show()const;
};class B :public A
{
private:A a;double c;double r;double q;double gd()const;
public:B();double gc()const;double gr()const;double gq()const;double ga();void de();void wi();void se();void show()const;
};

(1)吸收基类成员
在C++继承中,第一步是将基类的成员全盘接收,这样,派生类实际上就包含了它的全部基类中除构造函数和析构函数之外的所有成员。**在派生过程中构造函数和析构函数都不被继承。**在这里,派生类B继承了基类A中除构造函数和析构函数之外的所有非静态成员:i,b,r函数,e函数,gi函数,gb函数,show函数。经过派生过程,这些成员便存在于派生类之中。

(2)改造基类成员
对基类成员的改造包括两个方面:一个是基类成员的访问控制问题,主要依靠派生类定义时的继承方式来控制。另一个是对基类数据或函数成员的覆盖或隐藏,隐藏就是简单地在派生类中声明一个和基类数据或函数同名的成员,例如上例中的show函数。如果派生类声明了一个和某基类成员同名的新成员(如果是函数成员,则参数表也要相同,参数不同的情况属于重载),派生的新成员就隐藏了外层同名成员。 这时派生类中或者通过派生类的对象,直接使用成员名就只能访问到派生类中声明的同名成员,这称为同名隐藏。在上例中,派生类B中的show函数就隐藏了基类A中的同名函数。

(3)添加新的成员
派生类新成员的加入是继承与派生的核心,是保证派生类在功能上有所发展的关键。可以根据实际情况的需要,给派生类添加适当的数据和函数成员,来实现必要的新增功能。在上例,派生类B中就添加了数据成员a,c,r,q。

由于在派生过程中,基类的构造函数和析构函数不能被继承,因此要实现一些特别的初始化和扫尾清理工作,就需要在派生类中加入新的构造函数和析构函数。例如派生类B中的构造函数B()。

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

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

相关文章

C#设计模式之抽象工厂

抽象工厂模式是一种创建型设计模式,用于提供一个统一的接口来创建相关或依赖对象的系列,而无需指定具体的类。当需要满足以下情况之一时,可以考虑使用抽象工厂模式:创建一组相关的产品:抽象工厂模式适用于创建一系列相…

30岁程序员第一次失败的餐饮创业经历

背景介绍 我什么都比较晚,我比大多数人晚了两年毕业,事业稳定也比别人晚。直到去年,我才跳槽到一家外企外包工作获得相对满意的薪资。但即使如此,与更有经验的人相比,我仍然有很大的差距,自己也尚未积累足…

[CKA]考试之PersistentVolumeClaims

由于最新的CKA考试改版,不允许存储书签,本博客致力怎么一步步从官网把答案找到,如何修改把题做对,下面开始我们的 CKA之旅 题目为: Task 创建一个名字为pv-volume的pvc,指定storageClass为csi-hostpath-…

HTML中元素和标签有什么区别?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 标签(Tag)⭐元素(Element)⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&a…

Leetcode-每日一题【剑指 Offer 17. 打印从1到最大的n位数】

题目 输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。 示例 1: 输入: n 1输出: [1,2,3,4,5,6,7,8,9] 说明: 用返回一个整数列表来代替打印 n 为正整数 解题思路 前置知识 M…

嵌入式面试八股文

一、C/C题目 1.1.strcat、strncat、strcmp、strcpy,那些会导致内存溢出?如何改进? strcmp:与内存溢出没有关系,其功能为比较两个字符串是否相等。strcpy:把源字符串拷贝到目的内存中,如果源字符…

kubernetes基于helm部署gitlab

kubernetes基于helm部署gitlab 这篇博文介绍如何在 Kubernetes 中使用helm部署 GitLab。 先决条件 已运行的 Kubernetes 集群负载均衡器,为ingress-nginx控制器提供EXTERNAL-IP,本示例使用metallb默认存储类,为gitlab pods提供持久化存储&…

将word每页页眉单独设置

在进行论文排版的时候,总是会出现页眉的页码设置问题,比如出现奇数或偶数页码一致,尝试将前面页码改掉,后面再修改前面也进行了变动,将每页页眉单独设置: (1)在第一页的最后一行输入…

OPENCV C++(四)形态学操作+连通域统计

形态学操作 先得到一个卷积核 Mat kernel getStructuringElement(MORPH_RECT,Size(5,5)); 第一个是形状 第二个是卷积核大小 依次为腐蚀 膨胀 开运算 闭运算 Mat erodemat,dilatemat,openmat,closemat;morphologyEx(result1, erodemat, MORPH_ERODE, kernel);morphologyEx…

智能指针shared_ptr:自定义删除器

重点&#xff1a; 1.普通指针转化成智能指针。 2.智能指针创建的时候&#xff0c;第二个参数是自定义删除器&#xff0c;默认情况下&#xff0c;shared_ptr调用delete()函数。 class A { public:void Get() { cout << b << endl; }; private:int b{ 10 }; };clas…

Pandas

系列文章目录 第一章 python数据挖掘基础环境安装和使用 第二章 Matplotlib 第三章 Numpy 文章目录 系列文章目录一、介绍1.1 为什么用Pandas&#xff1f;1.2 核心数据结构1.3 DataFrame1.3.1 结构1.3.2 常用属性1.3.3 常用方法1.3.4 DataFrame索引的设置修改行列索引值重设索…

git仓库与本地暂存区的同步问题

向下同步 对于远程仓库的项目&#xff0c;初始化一个配置文件&#xff0c;配置远程仓库及相关信息&#xff0c;赋值远程仓库的地址&#xff0c;使用git pull命令即可拉取仓库代码。 git pull [remote_addr] 该部分完成向下同步 向上同步 向上同步时会遇到很多的问题&#xf…

utf8mb4_general_ci 和utf8mb4_unicode_ci有什么异同,有什么优劣

utf8mb4_general_ci 和 utf8mb4_unicode_ci 都是 MySQL 数据库中的字符集和排序规则&#xff08;collation&#xff09;。它们主要用于指定字符数据的排序和比较规则&#xff0c;以确保在数据库中对字符串进行查询和比较时得到正确的结果。 异同点&#xff1a; 1. utf8mb4_gen…

Redis ERR Protocol error: invalid multibulk length

异常信息 org.springframework.data.redis.RedisConnectionFailureException: ERR Protocol error: invalid multibulk length; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: ERR Protocol error: invalid multibulk lengthCaused by: red…

《手把手教你》系列基础篇之4-python+ selenium自动化测试-xpath使用(详细教程)

1. 简介 俗话说&#xff1a;磨刀不误砍柴工&#xff0c;因此在我们要开始写自动化脚本之前&#xff0c;我们先来学习和了解几个基本概念&#xff0c;在完全掌握了这几个概念之后&#xff0c;有助于我们快速上手&#xff0c;如何去编写自动化测试脚本。 元素&#xff0c;在这个…

vue-制作自动滚动效果

第一步&#xff1a;下载 可以查看官方地址chenxuan0000 npm i vue-seamless-scroll -save 第二步&#xff1a;引用 import vueSeamlessScroll from "vue-seamless-scroll";//注册components: {vueSeamlessScroll,}, 第三步&#xff1a;使用 <vue-seamless…

MongoDB面试题

1. NoSQL 数据库是什么意思?NoSQL 与 RDBMS 直接有什么区别?为什么要使用和不使用 NoSQL 数据库?说一说 NoSQL 数据库的几个优点? NoSQL 是非关系型数据库&#xff0c;NoSQL Not Only SQL。 关系型数据库采用的结构化的数据&#xff0c;NoSQL 采用的是键值对的方式存储数…

常用数据处理方式

文章目录 一、不同格式数据读取及转换split data into X and y二、数据预处理1、去重2、删除某一列3、删除两行4、date转字符串5、修改类型6、修改日期类型7、修改字段名8、加年月9、 删除字段10、 查看数据中顶部10%的数据11、设置索引12、判断空值13、排序14、 模糊查询15、修…

linux部署springboot项目中文乱码

问题描述&#xff1a; 将springboot项目打成jar包部署到linux服务器发现中文乱码 解决办法&#xff1a; java -Dfile.encodingutf-8 -jar xxxxx.jar转载至&#xff1a;https://blog.csdn.net/qq_39706515/article/details/119807632

Java---使用lombok简化实体类的编写----不要再写getter+sertter方法了

目录 使用lombok简化实体类的编写 首先&#xff1a; 加入lombok依赖&#xff1a; 然后 加上一个注解&#xff1a;Data 使用lombok简化实体类的编写 首先&#xff1a; 加入lombok依赖&#xff1a; <dependency><groupId>org.projectlombok</groupId>…