C++初识多态(1)

1.多态要解决的问题(引入)

任何一种机制的存在,必然是有其存在的意义的,例如我们前面学过的函数重载,运算符重载,以及引用等等,都是解决一些特殊问题的;

下面通过一些具体的例子,说明一下多态这种机制是解决什么问题的?

(1)上面的代码看着比较多,其实都是一些极其简单的语句,定义两个类,对于其中的变量进行设置,定义一个函数可以打印输出类里面的变量的结果;其中这两个类的定义的函数作用都是一样的,一个多变量的值进行设置,一个对于变量的值进行打印输出;

(2)这个a类就是我们熟知的父类,b类就是派生类,也叫做子类;

(3)在主函数里面,我们分别使用a类和b类定义了一个对象,里面使用注释表明了三种不同的情况,这三种情况就是我们多态就要解决的三类问题;

(4)第一种情况就是让b1对象赋值给a1,然后我们想使用a1这个对象调用相应的函数,我们在写的时候就会发现这个a1虽然是b1的父类,但是a1这个对象是没有办法调用b1类里面的任何函数的

上面的就是编译器自动识别的函数(只有这些弹出的函数才可以被a1这个对象进行调用) ,我们发现在b这个类里面定义的函数,是没有办法被我们的a1对象使用的,这个就是第一个问题;

(5)第二种情况是定义了一个指针变量,这个指针变量指向的是b1这个对象,我们会发现这个指针虽然指向的是b1这个对象,他仍然只能调用和a这个类相关的函数,对于b这个类里面进行定义的一些函数,他是没有权限进行使用的,这个也是一个问题;

(6)第三类问题是关于引用的问题,我们使用af1作为b1这个对象的别名,我们使用af1这个别名进行函数调用的时候,就会发现这个af1引用能够调用的函数也不会有b这个类里面的一些函数的;

(7)通过上面的案例,针对这些共性的问题:父类无法调用子类里面定义的一些函数 ,无论是普通的对象,还是指针变量和引用类型都是没有办法调用子类里面定义的一些函数的,这个就是多态将要解决的问题;

我们在主函数里面原本是对a1进行设置的100,但是这三种情况的打印结果都是一个比较大的随机值,可见是有问题的;

(8)对于打印的结果是随机值的这种情况,我们简单的介绍一下它的原理,就是a类是父类,b类是子类,我们的子类是继承父类一些东西的,我们在父类a里面定义了ii这个变量,因为b类是父类,就会继承a类里面的ii这个变量,自己是创建了jj这个变量的,所以b1里面就有ii和jj这两个变量

我们上面的这张图就是原理的概括,你现在可能看的不是很明白,经过我下面的介绍,相信你就可以明白了:

首先,我们要清楚a1对象里面的i这个成员变量我们原本是赋值100的,b1对象是继承a类创建的a1对象,但是这里的继承并不是真正的全部拷贝过来,而是吸收了父类里面的成员变量i,但是我们并没有对于这个成员变量进行任何的操作,因此这个时候b1这里的对象的值是随机值,接下来我们写的是a1=b1,相当于是把b1拷贝给了a1这个对象,这个时候b1里面的随机值(打印出来的负8亿多的那个数字)就带入到了a1对象里面去,就把a1对象里面原来的100这个数字给覆盖掉了;

其实通过上面的图也是可以看出来的,我们在执行a1=b1这条语句的时候,j=200这个成员变量已经同步到了父类a1里面,但是我们的a1对象不可以直接对这个对象进行使用;

这个时候我们再调用showa这个函数进行打印输出结果就会看到这个随机数字,这个兼容性规则就是一种弊端,什么弊端呢?我们的a1=b1这句代码的原本的意思是想要把b1这个对象里面的东西赋值给a1,这样我们使用a1就可以调用b1里面的一些函数了,但是这个兼容性的规则不但不会这样做,反而会把我们的父类里面的100给覆盖掉,这样就无功而返了。 

2.虚函数

(1)什么是虚函数,顾名思义,虚函数就是函数里面的一种,在我们的普通的函数里面加上virtual就可以把普通的函数变成虚函数;使用虚函数就可以解决我们上面遇到的子类的b1因为赋值使得a1里面的ii也改变成为随机值

上面的就是我们修改之后的函数,两个类里面的4个函数都是没有返回值的,我们在void前面加上virtual就可以把普通的函数修改为虚函数,针对前面体积道德第二种情况,我们不进行任何修改,调用showa函数,打印的结果就是我们设置的200,而不是那个随机数;

(2)虚函数是怎么在这个题目里面发挥自己的作用的:

之前我们是无法使用父类对象调用子类里面的新增成员变量的,但是加上虚函数之后;

我们重新进行设计,还是定义一个b1对象,因为我们已经把两个类里面的函数的名字改为相同的了,因此我们写下b1.set的时候就会出现同名覆盖的现象;

为了达到效果,我们可以加上类名和域作用限定符,这样我们的39行代码就是对b类里面的j变量进行赋值,40行里面就是对a类里面的i变量进行赋值;

pa1这个指针变量指向的是b1这个对象,这个对象是a类的,这个时候是可以使用父类a创建的指针访问子类里面的函数show的,这个就解决了因为兼容性而出现的缺陷,50行就是对我们定义的指针进行初始化;

3.多态的表现(2)------引用

之前我们没有多态的时候,使用这个引用是打印的随机值,多态加入之后,让af1作为b1对象的别名,我们使用af1进行调用函数,就会打印我们设置给b1对象的200;(实际上这个和编译器的版本有关,高版本的编译其实可以实现这个效果的,低版本的编译器无法实现)

在我们之前讲的第一种场景下面,我们打印的随机值,引入多态之后,打印结果就是300,可见b1对象对于a类这个作用域里面的set函数的调用的是发挥作用的,因为我们原本是a1.set(100),正常输出的结果应该是100,但是打印结果是300,说明这个b1.a::set()可以让b1这个 父类里面的a1对象的值从原来的100重置为现在的300;

但是当我们想使用父类a1调用b类里面的函数的时候,发现还是不行,这个时候就说明多态无法解决这个问题;

 

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

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

相关文章

组合模式(Composite)——结构型模式

组合模式(Composite)——结构型模式 组合模式是一种结构型设计模式, 你可以使用它将对象组合成树状结构, 并且能通过通用接口像独立整体对象一样使用它们。如果应用的核心模型能用树状结构表示, 在应用中使用组合模式才有价值。 例如一个场景…

剁手党必看——转转红包使用规则与最优组合计算全解析

​ 1、省钱攻略基础之“了解平台红包使用规则” 2、举个栗子 3、最优红包组合计算方法进化过程 3.1、初代“笛卡尔乘积”版 3.2、二代“边算边比较Map聚合”版 3.3、三代“边算边比较数组索引定位”版 4、总结 1、省钱攻略基础之“了解平台红包使用规则” 规则一&#x…

介绍 ffmpeg.dll 文件以及ffmpeg.dll丢失怎么办的五种修复方法

ffmpeg.dll 是一个动态链接库文件,属于 FFmpeg运行库。它在计算机上扮演着非常重要的角色,因为它提供了许多应用程序和操作系统所需的功能和组件。当 ffmpeg.dll 文件丢失或损坏时,可能会导致程序无法正常运行,甚至系统崩溃。下面…

数据结构-线性表-链表-2.3-4

试编写在带头结点的单链表L中删除一个最小值结点的高效算法(假设最小值结点是唯一的)。 使用四个指针,p,pre,minp,minpre 用p从头至尾扫描单链表,pre指向*p结点的前驱,用minp保存最小结点的指针(初始认为…

C#读sqlite数据库

using System.Data.SQLite;//若没有库需要在Nugut下载 private void ReadDatabase() { //判断有无数据库 if (!File.Exists(dbPath)) { SQLiteConnection.CreateFile(dbPath); MessageBox.Show(…

紫外激光打标机适合在哪些材料表面进行标记

紫外激光打标机适合在多种材料表面进行标记,特别是那些对热敏感或者需要高精度、高清晰度标记的材料。以下是一些常见的适用材料: 1. 塑料:紫外激光打标机在塑料材料上表现尤为出色,因为紫外激光的短波长和高能量密度使得它能够在…

Python | Leetcode Python题解之第70题爬楼梯

题目: 题解: class Solution:def climbStairs(self, n: int) -> int:a, b 1, 1for _ in range(n - 1):a, b b, a breturn b

TCP长连接短链接

1、短连接 短连接是指通讯双方有数据交互时,就建立一个连接,数据发送完成后,则断开此连接,即每次连接只完成一项业务的发送。 2、长连接 长连接是指在一个连接上可以连续发送多个数据包,在连接保持期间,…

Nginx启动后IP加端口不能正常访问

背景介绍 新增NGINX配置文件后,重启nginx无法使用IP端口访问服务,域名可以访问服务。NGINX启动不报错,测试nginx配置文件nginx -t也没问题。 定位问题思路与步骤 查看NGINX配置文件 发现NGINX配置文件中的user是www user www www;查看N…

Linux中通过命令执行Shell脚本不生效问题

Linux中通过命令执行Shell脚本不生效问题 文章目录 Linux中通过命令执行Shell脚本不生效问题1. 执行.sh设置export不生效问题2. 可能导致的原因3. 解决方法1. 通过点(.)来执行shell脚本2. 通过source来执行shell脚本 1. 执行.sh设置export不生效问题 执行命令./script.sh后发现…

深度学习实战77-基于CNN+BiLSTM的异常用电行为的识别算法研究与实战

大家好,我是微学AI,今天给大家介绍一下深度学习实战77-基于CNN+BiLSTM的异常用电行为的识别算法研究与实战。 在智能电网的快速发展背景下,电力系统的安全稳定运行显得尤为重要。异常用电行为,如非法窃电、设备故障导致的非正常耗电等,不仅影响电网的经济效益,还可能威胁…

ORA-51803: Vector dimension count must match the dimension count 错误解决

ORA-51803: Vector dimension count must match the dimension count 错误解决 0. 错误信息1. 解决方法 0. 错误信息 错误信息如下, oracledb.exceptions.DatabaseError: ORA-51803: Vector dimension count must match the dimension count specified in the col…

C语言(操作符)2

Hi~!这里是奋斗的小羊,很荣幸各位能阅读我的文章,诚请评论指点,关注收藏,欢迎欢迎~~ 💥个人主页:小羊在奋斗 💥所属专栏:C语言 本系列文章为个人学习笔记&#x…

[C++]智能指针的实现:auto_ptr, shared_ptr, weak_ptr

auto_ptr 简介 交换资源的管理权&#xff0c;将被拷贝资源置空&#xff0c;很危险&#xff0c;一般被禁用 代码实现 namespace memory {template<typename T>class auto_ptr{public:auto_ptr(T* ptr):_ptr(ptr){}auto_ptr(auto_ptr<T>& ap){_ptr ap._ptr;…

快速话术本(常用文本快速复制工具)EXE成品+软件源码

功能介绍 经常性需要重复性的输入几个不同的文本&#xff0c;来回复制很麻烦&#xff0c;这个小工具可以帮你解决&#xff0c;把要经常输入的文本添加进去&#xff0c;点击即可复制~ 链接&#xff1a;https://pan.baidu.com/s/1TqtJ_Xb10k4j3dxSRjz47Q?pwdsl4l 提取码&…

38.分布式文件系统 - Minio

文章目录 分布式文件系统MinIO安装和启动docker中MinIO的使用podman 虚拟机里使用Docker启minio配置&#xff08;成功访问&#xff09; Java连接minio 分布式文件系统 MinIO 官网&#xff1a;[https://min.io] 中文&#xff1a;[https://www.minio.org.cn/] [http://docs.mi…

Guid转换为字符串

在理想情况下&#xff0c;任何计算机和计算机集群都不会生成两个相同的GUID。GUID 的总数达到了2128&#xff08;3.41038&#xff09;个&#xff0c;所以随机生成两个相同GUID的可能性非常小&#xff0c;但并不为0。GUID一词有时也专指微软对UUID标准的实现。 (1). GUID&#…

如何避免在抓取Google时被屏蔽?代理IP的7个使用误区

在当今数字化时代&#xff0c;数据采集和网络爬取已成为许多企业和个人必不可少的业务活动。对于爬取搜索引擎数据&#xff0c;特别是Google&#xff0c;使用代理IP是常见的手段。然而&#xff0c;使用代理抓取Google并不是一件轻松的事情&#xff0c;有许多常见的误区可能会导…

【FFmpeg】Filter 过滤器 ① ( FFmpeg 过滤器简介 | 过滤器概念 | 过滤器用法 | 过滤器工作流程 | 过滤器文档 | 过滤器分类 )

文章目录 一、FFmpeg 过滤器 Filter 简介1、FFmpeg 过滤器概念2、FFmpeg 过滤器用法3、FFmpeg 过滤器工作流程4、FFmpeg 过滤器文档 二、FFmpeg 过滤器 分类1、过滤器分类 - 根据处理数据类型分类2、过滤器分类 - 根据编码器位置分类3、过滤器分类 - 根据功能分类 FFmpeg 相关文…

typescript的入门到吐槽:看了typescript,发现前端真的卷,

typescript TypeScript 是一种由微软开发的自由和开源的编程语言。它是 JavaScript 的一个超集&#xff0c;而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。 TypeScript 与 JavaScript 的区别 其实就是对JavaScript的封装&#xff0c;把一个弱类型语言封…