[c++]多态的分析

多态详细解读

    • 多态的概念
      • 多态的构成条件
    • 接口继承和实现继承:
  • 多态的原理:
      • 动态绑定和静态绑定
    • 多继承中的虚函数表


多态的概念

-通俗的来说:当不同的对象去完成某同一行为时,会产生不同的状态。

多态的构成条件

  • 必须通过基类的指针或者引用调用虚函数1
  • 虚函数的重写2三同(函数名,参数,返回值)
    EG:在这里插入图片描述

函数重写的两个例外:

  • 协变(基类与派生类虚函数返回值类型不同):
    但是仅仅支持返回各自的对象的指针或者引用
  • 析构函数的重写(基类与派生类析构函数的名字不同):
    虽然析构函数的函数名不同,但是编译器会做特殊的处理,统一处理成destructor(前提是基类的析构函数加了virtual)

接口继承和实现继承:

  • 普通函数的继承叫做实现继承,虽然连函数名和参数等等也全部继承,但是主要是继承实现,且派生类可以直接使用。
  • 虚函数的继承是接口继承,为了实现重写(重写实现操作)

到这里可能有些小伙伴会不太理解接口是什么,这里我们用一个例子来解释:
问:*p->test( )此时打印出来的结果是什么呢?
是不是第一眼就觉得是B->0呢?我们来看看解析:
在这里插入图片描述

多态的原理:

  • 首先我们先要理解函数虚表这个概念,函数虚表里面存放着虚函数的地址。(为了描述方便,下面都称之为虚表)
  • 当满足多态的两个条件之后:如果传给基类的指针的是子类对象的地址,那就会去调用子类的虚表里面重写之后的对应函数,如果传的是基类对象的地址,那么就会去基类自身的虚表里面找对应的函数。

图例:
在这里插入图片描述
这时候有同学就要问了:这个基类的虚表和子类的虚表是同一张吗?虚表到底有几张?

  • 只要有虚函数,那么对于各种类,他们都有各自的虚表。并且如果派生类(既然叫做派生类,说明是继承了某个类作为基类)中有实现虚函数fun1的重写,那么就会在自身的虚表中覆盖掉从原来基类中的继承下来的fun1的实现(虚函数是接口继承,原函数的实现被覆盖),正因如此才能实现多态。

  • 所以基类和子类的虚表不是同一张,每个类都有自己的虚表

动态绑定和静态绑定

  • 静态绑定就是在程序编译期间,就明确了程序的行为。比如函数的重载
  • 动态绑定也叫做后期绑定,就是在程序运行期间,根据传过来的类型去*确定具体的行为*,比如上述的不同的身份去购买车票会。
  • 细节点:虚表是在编译的时候就生成了,但是对象中只存储指向虚表的指针(由于虚表实际叫做函数指针数组,那么虚表的指针就叫做函数指针数组的指针,这个指针是在对象执行构造函数的时候生成的。)

多继承中的虚函数表

这里主要清楚:对于多继承的派生类,其本身未重写的虚函数放在其第一个继承的父类部分的虚表中。(但是这里要意识到大的来看此处仍然是在派生类的虚表,是派生类虚表中所继承的父类的虚表部分。)
在这里插入图片描述


  1. 虚函数:被virtual修饰的成员函数就称为虚函数 ↩︎

  2. 虚函数的重写:虚函数的重写(覆盖):派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型、函数名字、参数列表完全相同),称子类的虚函数重写了基类的虚函数。 ↩︎

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

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

相关文章

合并两个有序链表(C语言)———链表经典算法题

题目描述​​​​​​21. 合并两个有序链表 - 力扣(LeetCode): 答案展示: 迭代: /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* mergeTwoLis…

【docker 】push 镜像到私服

查看镜像 docker images把这个hello-world 推送到私服 docker push hello-world:latest 报错了。不能推送。需要标记镜像 标记Docker镜像 docker tag hello-world:latest 192.168.2.1:5000/hello-world:latest 将Docker镜像推送到私服 docker push 192.168.2.1:5000/hello…

【吃透Java手写】2-Spring(下)-AOP-事务及传播原理

【吃透Java手写】Spring(下)AOP-事务及传播原理 6 AOP模拟实现6.1 AOP工作流程6.2 定义dao接口与实现类6.3 初始化后逻辑6.4 原生Spring的方法6.4.1 实现类6.4.2 定义通知类,定义切入点表达式、配置切面6.4.3 在配置类中进行Spring注解包扫描…

python中如何把list变成字符串

python中如何把list变成字符串?方法如下: python中list可以直接转字符串,例如: data ["hello", "world"] print(data1:,str(data)) 得到结果: (data1:, "[hello, world]") 这里将整个…

芋道----工作流中添加邮件通知

1、配置邮件发送的账号 2、编辑邮件的内容模板 如何新建邮箱,直接查看芋道官网即可,已经讲解的很详细了,可以直接点击下方链接 邮件配置 | ruoyi-vue-pro 开发指南 (iocoder.cn)https://doc.iocoder.cn/mail/#_3-1-%E6%96%B0%E5%BB%BA%E9%82…

Android项目转为鸿蒙,真就这么简单?

最近做了一个有关Android转换成鸿蒙的项目。经不少开发者的反馈;许多公司的业务都增加了鸿蒙板块。 对此想分享一下这个项目转换的流程结构,希望能够给大家在工作中带来一些帮助。转换流程示意图如下: 下面我就给大家介绍,Android…

26、Qt使用QFontDatabase类加载ttf文件更改图标颜色

一、图标下载 iconfont-阿里巴巴矢量图标库 点击上面的链接,在打开的网页中搜索自己要使用的图标,如:最大化 找到一个自己想用图标,选择“添加入库” 点击“购物车”图标 能看到刚才添加的图标,点击“下载代码”(需要…

手撕C语言题典——移除链表元素(单链表)

目录 前言 一.思路 1)遍历原链表,找到值为 val 的节点并释放 2)创建新链表 二.代码实现 1)大胆去try一下思路 2)竟然报错了?! 3)完善之后的成品代码 搭配食用更佳哦~~ 数据结构之单…

双向链表(详解)

在单链表专题中我们提到链表的分类,其中提到了带头双向循环链表,今天小编将详细讲下双向链表。 话不多说,直接上货。 1.双向链表的结构 带头双向循环链表 注意 这几的“带头”跟前面我们说的“头节点”是两个概念,实际前面的在…

【机器学习与实现】线性回归分析

目录 一、相关和回归的概念(一)变量间的关系(二)Pearson(皮尔逊)相关系数 二、线性回归的概念和方程(一)回归分析概述(二)线性回归方程 三、线性回归模型的损…

vue开发网站—①调用$notify弹窗、②$notify弹窗层级问题、③js判断两个数组是否相同等。

一、vue中如何使用vant的 $notify(展示通知) 在Vue中使用Vant组件库的$notify方法来展示通知,首先确保正确安装了Vant并在项目中引入了Notify组件。 1.安装vant npm install vant --save# 或者使用yarn yarn add vant2.引入:在ma…

springboot整合redis多数据源(附带RedisUtil)

单数据源RedisUtil(静态) 单数据源RedisUtil,我这里implements ApplicationContextAware在setApplicationContext注入redisTemplate,工具类可以直接类RedisUtil.StringOps.get()使用 package com.vehicle.manager.core.util;import com.alibaba.fastjson.JSON; import lombok.e…