023 - C++ 继承

news2024/11/16 23:56:55

本期我们学习 C++ 面向对象编程中的继承

面向对象编程是一个巨大的编程范式,类之间的继承是它的一个基本面,它是我们可以实际利用的最强大的特性之一。

先了解这些

继承允许我们有一个相互关联的类的层次结构。展开来说,它允许我们有一个包含公共功能的基类,我们可以从基类中分离出来,基于父类(基类)中创建子类。

类继承的主要作用是它可以帮助我们避免代码重复。

使用类继承后,我们就不需要一遍又一遍的重复一些代码了,我们可以把类之间的所有公共功能放在一个父类中。然后从基类(父类)创建(派生)一些类,稍微改变下功能或者引入全新的功能。这样我们就不用像写模板那样不断重复了。

我们来看看如何在源代码中定义它。

oeYcqt.png

上面的代码中我们创建了一个 Entity 类,它用来描述游戏中的所有实体对象。

在我们游戏中我们可能有很多非常具体的实体,然而在某些方面,它们的功能是一样的。

例如也许每个实体在我们的游戏中都有自己的位置,这可以通过两个 float 的变量来表达。在上面的代码中,我们有设置了 float X和 float Y。

我们可能想赋予每个实体移动的能力,这可以通过 Move 方法实现,它有 xa 和 ya 两个参数作为我们坐标数据的偏移量。

好了,现在我们有了一个基类,Entity 类。

我们说过在游戏中创建的每一个实体都将是具有这些特征的。

我们继续创建一个新类型的实体。

oeY0PE.png

在上面的代码中,我们创建了一个 Player 类,目前还没有用到所谓的继承概念。我们是从零开始的,这个 Player 类也有位置,因为这也是一个实体,它需要位置信息。

我们还想让它能够移动,所以我们定义 Move 函数,你可以看到当前我们完成的东西和上面的 Entity 类很像。

接下来这个 Player 类有我们想要存储的额外数据。例如姓名 Name 或打印姓名的方法 PrintName,我们加上了这些内容。

到这里,你可以看到它们实际上已经是不同的类了。

然而能看到有相当多的代码只是被复制粘贴。为了改变这种状况,我们能做的就是利用继承。

继承

我们可以扩展 Entity 实体类来创建 Player 类,然后让它存储新数据,比如姓名 Name 或打印姓名的方法 PrintName。

现在让我们把 Player 变成 Entity 的子类。

oeYdTu.png

这需要我们在类声明后写一个冒号,然后写上 public Entity。

现在在我们写的代码中,发生了一些事情:Player 类现在不仅拥有 Player 类型,它也有 Entity 类型,它现在是两种类型了。

类型在 C++ 中是相当复杂的主题。一方面它们实际上并不存在,然而另一方面,它们又会在很多地方制造麻烦,后面的系列中我们再去深入了解它是如何工作的。

Player 现在拥有 Entity 拥有的所有东西,比如拥有类成员 X 和 Y,比如 Move 方法。因为它们本身也在 Player 中,所以现在我们把 Player 类中和 Entity 所有重复的代码都删掉,留下一些不一样的东西就可以了,这些是我们的附加功能。

oeYvUv.png

现在这个 Player 类看起来很干净。

我要提醒你们,它实际上也是一个 Entity,这意味着仅仅看这个类的内容并不能告诉我们关于它的所有信息,如果想全面了解的话,我们必须去找 Entity,看看它有什么。因为就 Player 而言,任何在 Entity 类中不是私有的东西实际上都可以被 Player 访问。

验证

让我们来测试一下。

oeYNnY.png

在上面的代码中,我们创建一个 Player 类的实例 player。它不仅可以调用 printName 函数,——这个函数本身就是在 Player 类里面的。因为现在还没有名字的具体内容,所以直接运行会出问题。而且也可以调用 Move 函数,并且可以访问 X,就好像它就是一个 Entity 一样,因为它继承了 Entity 所有的功能。

其实在这里可以应用的一个概念是 多态。这个内容将在以后的内容中深入探讨。简单来说,多态是一个单一类型但是有多个类型的意思。

还记得我提到的 Player 不只是 Player类型,而且也是一个 Entity类型。这意味着我们可以在任何我们想要使用 Entity 的地方使用 Player。因为 Player 拥有 Entity 所拥有的一切,再加上多一点点东西,它甚至不需要有更多那一点点东西,它们两个也可能是完全一样的。——Player 总是 Entity 的超集,这意味着 Player 总是会拥有 Entity 所拥有的一切,也可能更多一点。

举个例子。

如果我想创建一个打印 Entity 对象的函数,例如访问 X 和 Y 变量,并让它们打印到控制台,我可以传入 Player 对象到相同的函数中,即便这个函数原本是接受 Entity 类型的参数。

可以这样操作的原因是,Player类型必定会有这些 X 和 Y 变量。作为 Entity 类的子类,它包含了 Entity 所有的东西。我们还可以做很多类似的事情。

我们也可以改变父类或基类的行为。例如通过重写一个方法,并给它新的代码来代替它(父类方法)运行。

但本期的主要内容是继承,它是我们一直在使用的一种方式,是我们扩展现有类并为基类提供新功能的一种方式,这是面向对象编程最重要的东西之一。

记住当你创建一个子类时,它将包含它父类所含的一切。

我还有一个证明这个的方法。

另一种验证方法

记得我们基类中有浮点数 X 和 Y 。

我们通过使用 sizeof 函数计算 Entity 的对象的大小并打印到控制台。

oeYDwM.png

你可以看到输出的它的大小是8。没问题,因为 Entity类中有两个浮点数 XY。

现在让我们继续打印 Player 的大小。

假设我们删除继承的代码,那么 Player 只是一个独立的类,只有这个 const char指针,在32位的应用程序中,这应该是 4 字节的内存。

然而既然我们扩展了Entity,这意味着它继承了 Entity 类中的所有变量,所以实际上应该是4+4+4 = 12。

运行下面的程序看一下对不对。

oeY7tg.png

的确如此。

你可以看到我们实际上继承了 Entity 拥有的所有东西。好像我们复制粘贴了所有东西。

请记住,这些类的大小和内存实际上是可以变化的。

那么,除了这个区别还有其他的变化吗?

有的,如果我们开始重写函数和 Player 类,那么我们就需要维护一个V表(虚函数表),也就是要占用额外的内存。这个先简单了解一下,本期先不讲这个。

以上就是继承在 C++ 类中的如何工作的要点。

最后的话

在本系列课程中我们将分解所有与面向对象编程相关的独立概念,多态、继承等等。所有这些概念都值得好好研究。如果将整个体系如果比喻成一个物件,我还只是接触到了它的表面而已。

好了,本期的内容就是这些,下期再见。

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

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

相关文章

Ceph入门到精通-Ceph介绍及放置规范

2.cephadm介绍 2.1cephadm介绍 Cephadm 是随着 Ceph 新版本 v15.2.0(Octopus)发布的安装工具,并且不支持 Ceph的旧版本,Ceph中已经Cephadm 不依赖于外部配置工具,如 Ansible、 Rook 和 Salt,它通过 SSH 将管理器守护进程连接到主机…

通信中间件

通信中间件需要解决什么问题 分布式系统中两个不同的系统需要进行通信的时候,使用的是scocket编程,需要直接面对网络中的四层模型,编程时需要确定目标端的详细物理地址。这是非常不方便的。为了解决这个问题,需要通信中间件来屏蔽…

Linux系统编程学习 NO.1 ——操作系统的历史发展

什么是操作系统? 首先,需要明白一个概念操作系统的本质是系统软件,我们平时在电脑上的界面就是一种图形化的操作系统界面。界面上通常安装可执行应用程序如QQ,wps等等,这些应用程序被称为应用软件。大家买的电脑其实是…

【Java实战篇】Day14.在线教育网课平台--消息队列实现异步通知

文章目录 一、需求:支付通知1、需求分析2、技术方案3、集成RabbitMQ4、生产端发送消息5、消费方发送消息 二、需求:在线学习1、需求分析2、表设计与实体类3、接口定义--查询课程4、接口定义获取视频5、Service层开发6、FeignClient定义7、代码完善 三、需…

HOG+SVM分类器实践

文章目录 HOGSVM分类器实践制作SVM分类器导入所需的库提取HOG特征读取正样本和负样本训练分类器定义主函数小结 测试SVM分类器相关疑问1. 提取HOG特征为什么不能彩色图像呢?2. 出现如下错误3. 测试代码中,当我传入100*100的图片时候,为什么im…

Linux下安装Java8环境

查看主机是否已经安装Java环境 java -version 如下图所示,未找到java命令,则需要安装Java环境 JDK官网下载: https://www.oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.html 根据自己系统的位数下载相应版本…

基于Dokcer安装RabbitMQ

基于Dokcer安装RabbitMQ 一、RabbitMQ介绍 1.1 现存问题 服务调用:两个服务调用时,我们可以通过传统的HTTP方式,让服务A直接去调用服务B的接口,但是这种方式是同步的方式,虽然可以采用SpringBoot提供的Async注解实现…

第6章:集合

集合简介 一种无序且唯一的数据结构。不关心顺序,集合里面的元素都是唯一的。 栈,队列,链表他们里面都有可能出现重复的数据,但是集合里面的元素是唯一的。 栈,队列,链表它们都有自己的顺序,但是…

使用媒体查询实现移动端适配,媒体查询meta标签配置(@media screen and,min-width和max-width)

简述:我们在写网站的时候,难免会遇到需要做移动端适配的需求,今天来记录下使用媒体查询实现移动端的适配。媒体查询是一种CSS技术,可以根据设备屏幕的属性(如宽度、高度、方向和分辨率)选择应用特定样式&am…

火爆全网,JMeter接口自动化测试详细实战(超详细)吐血整理...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 JMeter接口自动化测…

深度学习 - 44.Gate 与 MMOE 实现多目标学习

目录 一.引言 二.摘要 Abstract 三.介绍 Introduction 四.相关工作 RELATED WORK 1.DNN 中的多任务学习 2.SubNet 集成与 Expert 混合 3.多任务学习应用 五.建模方法 MODELING APPROACHES 1.Shared-bottom Multi-task Model 2.Mixture-of-Experts 3.Multi-gate Mixt…

NOPI用法之自定义单元格背景色(3)

NPOI针对office2003使用HSSFWorkbook,对于offce2007及以上使用XSSFWorkbook;今天我以HSSFWorkbook自定义颜色为例说明,Office2007的未研究呢 在NPOI中默认的颜色类是HSSFColor,它内置的颜色有几十种供我们选择,如果不…

模态分解算法 EMD、EEMD、CEEMD

一、模态分解算法EMD算法介绍 (一)模态分解相关的算法有以下几类 IMF 固有模态函数\EMD经验模态分解\EEMD集合经验模态分解\CEEMD 互补集合经验\(EEMD的标准形式)CEEMDAN自适应噪声完备集合经验模态分解\VMD 变分模态分解 &…

Crypko.ai:动漫角色生成和设计平台

【产品介绍】 Crypko.ai是一个基于GAN(生成对抗网络)的高质量动漫角色生成和设计平台,可以让用户通过简单的操作,创造出各种风格和特征的动漫角色,并且可以对角色的头发、脸部、衣服、风格等进行编辑和调整。 Crypko.a…

【GNN】谱域图卷积

谱域图卷积 1. 谱域卷积的背景知识 1.1 谱域图卷积实现思路 f 1 ( t ) ⋆ f 2 ( t ) F − 1 [ F 1 ( w ) F 2 ( w ) ] f_1(t) \star f_2(t) F^{-1}[F_1(w)F_2(w) ] f1​(t)⋆f2​(t)F−1[F1​(w)F2​(w)] 1.2 如何定义图上的傅里叶变换 经典傅里叶变换: x ( …

人工智能+自助餐:一种有效减少食物浪费的创新方案

一、案例背景: 自助餐是一种受欢迎的餐饮形式,可以满足不同顾客的口味和需求。但是,自助餐也存在着浪费食物的问题,有的顾客拿得多吃得少,有的顾客只吃部分食物,剩下的扔掉。据统计,2022年中国…

【算法竞赛】实现约瑟夫问题的四种方法(附手绘图详解)

💌 博客内容:实现约瑟夫问题的四种方法 😀 作  者:陈大大陈 🚀 个人简介:一个正在努力学技术的准前端,专注基础和实战分享 ,欢迎私信! 💖 欢迎大家&…

视频剪辑配乐技巧 视频剪辑配音推荐

视频是视觉加听觉的艺术,视频的背景音乐不同,所呈现的效果也不同。接下来为大家带来大家视频剪辑配乐技巧,视频剪辑配音推荐的相关内容。 一、视频剪辑配乐技巧 视频剪辑时选好了配乐,视频就成功了一半。那如何找到合适的配乐呢…

yapi一键安装 文档开源系统

访问 GitHub - Ryan-Miao/docker-yapi: Docker build and run yapi as serviceDocker build and run yapi as service. Contribute to Ryan-Miao/docker-yapi development by creating an account on GitHub.https://github.com/Ryan-Miao/docker-yapi git clone https://githu…

Class类

package com.hspedu.reflection.class_;import com.hspedu.Cat;import java.util.ArrayList;/*** author 韩顺平* version 1.0* 对Class类特点的梳理*/ public class Class01 {public static void main(String[] args) throws ClassNotFoundException {//看看Class类图//1. Cla…