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 文件丢失或损坏时,可能会导致程序无法正常运行,甚至系统崩溃。下面…

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

紫外激光打标机适合在多种材料表面进行标记,特别是那些对热敏感或者需要高精度、高清晰度标记的材料。以下是一些常见的适用材料: 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

C语言(操作符)2

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

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

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

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

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

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

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

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

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

刨析YOLOv8的改进模块

1、YOLOv5回顾 这里粗略回顾一下,这里直接提供YOLOv5的整理的结构图吧:Backbone:CSPDarkNet结构,主要结构思想的体现在C3模块,这里也是梯度分流的主要思想所在的地方;PAN-FPN:双流的FPN,必须香,也必须快,但是量化还是有些需要图优化才可以达到最优的性能,比如cat前后…

淘宝扭蛋机小程序,开启你的惊喜探索之旅!

亲爱的淘宝用户们,我们非常高兴地宣布,全新的淘宝扭蛋机小程序即将上线!这是一款集合了趣味、惊喜与购物乐趣于一体的创新应用,让你在淘宝的海洋里,找到那份独特的快乐。 一、淘宝扭蛋机小程序是什么? 淘…

Qt与MySQL连接

QT连接Mysql数据库(详细成功版)-CSD N博客 我的MySQL是64位的,所以我的Qt的套件也需要是64位的 遇到的问题: (available drivers中已经有QMYSQL QMYSQL3,还是not loaded) QSqlDatabase: QMYS…

RAG 检索的底座:Milvus Cloud向量数据库

在业界实践中,RAG 检索通常与向量数据库密切结合,也催生了基于 ChatGPT + Vector Database + Prompt 的 RAG 解决方案,简称为 CVP 技术栈。这一解决方案依赖于向量数据库高效检索相关信息以增强大型语言模型(LLMs),通过将 LLMs 生成的查询转换为向量,使得 RAG 系统能在向…

团结引擎+OpenHarmony 3 通信

团结引擎和鸿蒙之间通信 因为 ts 并没有像 JAVA 有反射的调用,所以我们必须要像 Web GL 平台一样通过导出的行为告诉引擎到底哪些 ts 的接口可以给 C# 来调用。 1 在 Tuanjie 引擎里 需要一个tsllib文件,用于设置给导出对象 C#使用。就可以直接创建以 …

C++ | Leetcode C++题解之第72题编辑距离

题目&#xff1a; 题解&#xff1a; class Solution { public:int minDistance(string word1, string word2) {vector<vector<int>> dp(word1.size() 1, vector<int>(word2.size() 1, 0));for (int i 0; i < word1.size(); i) dp[i][0] i;for (int j…

大模型的概念与特点

在人工智能的浩瀚星空中&#xff0c;大模型犹如一颗璀璨的明星&#xff0c;引领着技术发展的方向。它们以巨大的参数规模和复杂的计算结构&#xff0c;展现出前所未有的智能潜力。本小节将从大模型的基本概念出发&#xff0c;逐步深入解析其发展历程、特点、分类以及泛化与微调…

【Java基础】字符串的内存情况及应用场景

String 特点 用双引号引起来的一串字符&#xff0c;字符串不变&#xff0c;它们的值在创建后不能被更改String str"hello";存储在堆中的字符串常量池已经定义过的字符串&#xff0c;再次定义时直接使用已有的字符串String类重写了**boolean equals(object obj)**方…

爱丁堡大学出新招,大小语言模型配合节约成本!

在大语言模型的应用中&#xff0c;往往面临着成本和性能权衡的问题。 一方面&#xff0c;大型LLM的参数量极大&#xff08;如70B&#xff09;&#xff0c;每次调用都可能带来更多的成本&#xff0c;而小型LLM&#xff08;如7B&#xff09;的成本则更容易被接受。 另一方面&am…

接收区块链的CCF会议--NDSS 2025 截止7.10 附录用率

会议名称&#xff1a;Network and Distributed System Security Symposium (NDSS) CCF等级&#xff1a;CCF A类学术会议 类别&#xff1a;网络与信息安全 录用率&#xff1a;2024年接收率19.5% Submissions are solicited in, but not limited to, the following areas: Ant…