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.mfbz.cn/a/603914.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

类和对象、this指针、类里的默认生成函数

🐶博主主页:ᰔᩚ. 一怀明月ꦿ ❤️‍🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C,linux 🔥座右铭:“不要等到什么都没有了…

【仪酷LabVIEW AI工具包案例】使用LabVIEW AI工具包+YOLOv5结合Dobot机械臂实现智能垃圾分类

‍‍🏡博客主页: virobotics(仪酷智能):LabVIEW深度学习、人工智能博主 🎄所属专栏:『仪酷LabVIEW AI工具包案例』 📑上期文章:『【YOLOv9】实战二:手把手教你使用TensorRT实现YOLOv…

升级PQC后,「谷歌浏览器」却频频报错......

上周Chrome 124发布后,默认启用了新的抗量子X25519Kyber768封装机制,不过,一些谷歌Chrome用户在使用后反应说,新版本的浏览器在连接网站、服务器和防火墙时出现了问题。 谷歌在8月份开始测试后量子安全TLS密钥封装机制&#xff0c…

嫦娥六号近月制动成功,建立月球基地又迈进一步!

嫦娥六号探测器在近月制动的关键时刻,北京航天飞行控制中心内弥漫着紧张而庄重的氛围。每一个航天科技工作者都屏息以待,他们的眼神中充满了期待与自豪。随着一系列精妙绝伦的指令如同琴弦上的音符般流畅地奏响,嫦娥六号探测器在万众瞩目的目…

使用SpringBoot+Redis做一个排行榜【推荐】

SpringBoot Redis实现排行榜 一、Zset有序集合介绍 Zset是一个没有重复元素的字符串集合。不同之处是有序集合的每个成员都关联了一个评分( score) ,这个评分( score)被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但是评分可以是重复了…

通讯录项目—顺序表实现

在上次我介绍顺序表后相信大家对顺序表有了一定的了解,现在就让我们来练练如何用它,这篇是在顺序表基础上新增的(建议看看线性表—顺序表实现-CSDN博客)。 目录 通讯录简介 创建用户信息 适配和理解通讯录 功能实现 初始化通讯录 销毁通讯录 增加…

为什么跑腿越来越受到年轻人的青睐

跑腿服务越来越受到年轻人的青睐,主要源于以下几个方面的原因: 1. 便捷快速:在快节奏的现代生活中,年轻人追求的是效率和速度。跑腿服务提供了一种即时、便捷的解决方案,使他们能够在繁忙的生活和工作中节省时间和精力…

鸿蒙开发实战:智能日志定位与高效调试技巧

前言 在鸿蒙系统的开发过程中,日志定位是一个关键的调试步骤。想象一下,如果你能够轻松地在繁杂的代码中快速定位到日志产生的位置,那将会极大地提高你的开发效率。今天,我将分享一套代码,它能帮助你实现这一目标。 效果展示 当你使用这套代码时,日志的打印效果将如下…

qt开发解压缩zip文件实现

作者开发环境:Qt5.8 ,win10 总体思路:首先我们编译zip源码,生成zip的动态库;然后再编译quazip源码,得到quazip的动态库;最后在我们的程序中去调用。 详细步骤: 1、编译zlib zlib…

Day22 代码随想录打卡|字符串篇---实现 strStr()

题目(leecode T28): 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1…

WSL2中使用USB串口实验

一、主要参考网站: Connect USB devices | Microsoft Learn 连接 USB 设备 | Microsoft Learn 二、安装usbipd-win WSL 本身并不支持连接 USB 设备,因此你需要安装开源 usbipd-win 项目 PS C:\Users\issta> winget install --interactive --exact dorssel.usbipd-win …

yaml配置文件的在深度学习中的简单应用

1 .创作灵感 小伙伴们再阅读深度学习模型的代码的时候,经常会遇到yaml格式的配置文件。用这个配置文件是因为我们在训练模型的时候会涉及很多的参数,如果这些参数东一个,西一个,我们调起来的时候就会很不方便,所以用y…

Springboot+vue项目人事管理系统

开发语言:Java 开发工具:IDEA /Eclipse 数据库:MYSQL5.7 应用服务:Tomcat7/Tomcat8 使用框架:springbootvue JDK版本:jdk1.8 文末获取源码 系统主要分为管理员和普通用户和员工三部分,主要功能包括个人中心,普通用户管理&…

4.用python爬取保存在text中的格式为m3u8的视频

文章目录 一、爬取过程详解1.寻找视频的m3u8链接2.从网页源码中寻找视频的m3u8链接的第二部分内容3.从视频的m3u8链接获取视频 二、完整的代码 一、爬取过程详解 1.寻找视频的m3u8链接 这个文档承接了爬虫专栏的 第一节.python爬虫爬取视频网站的视频可下载的源url&#xff0…

头歌实践教学平台:CG3-v2.0-图形几何变换

第1关:平移、缩放、旋转正方体 一. 任务描述 1. 本关任务 (1) 理解几何变换基本原理, 掌握平移、旋转、缩放变换的方法; (2) 根据平移算法原理补全translation、scale、rotation_x、rotation_y和rotation_z函数; (3) 根据几何变换基本原理,将main函数中的transla…

RK3568 学习笔记 : Linux emmc 内核启动 rootfs 根文件系统无法正常挂载问题的分析

问题描述 平台 : NanoPi-R5C 开发板 RK3568 平台。 手动编译的 Linux 内核,结果发现大概率 emmc 无法正常初始化,导致 rootfs 根文件系统无法正常挂载 Linux 内核版本: 6.1 Linux 内核代码位置: https://github.com…

上网行为监控软件有哪些(上网审计软件)【收藏】

上网行为监控软件(也被称为上网审计软件)正逐渐成为企业信息安全管理的必备工具。 没错! 这些软件通过对员工的上网行为进行全面、细致的监控和审计,帮助企业提升工作效率、保护数据安全,并规范员工的网络使用行为。 …

Springboot+vue项目健身房课程预约平台

开发语言:Java 开发工具:IDEA /Eclipse 数据库:MYSQL5.7 应用服务:Tomcat7/Tomcat8 使用框架:springbootvue JDK版本:jdk1.8 本系统主要实现了首页、个人中心、用户管理、教练管理、会员卡管理、购买会员管理、课程类型管理、课程信息管理、课程购买…

生信新包|LINGER·从单细胞多组学数据推断基因调控网络

题目:Inferring gene regulatory networks from single-cell multiome data using atlas-scale external data 原理 LINGER 是一个计算框架,旨在从单细胞多组学数据推断基因调控网络。 使用基因表达和染色质可及性的计数矩阵以及细胞类型注释作为输入&…

Linux下创建达梦数据库自动备份任务

分享一个自己用的银河麒麟下达梦数据库自动备份任务脚本。 达梦数据库备份脚本。按日期备份,备份后压缩为tar.gz文件,自动清理导出的文件。 备份脚本保留最后30天记录,以节省硬盘空间,可根据具体情况修改。 达梦数据库备份脚本 …
最新文章