C++多态----虚函数初级剖析

2023-11-05

多态说白了就是多种形态,在C++中不少的函数都可以实现多种形态,例如函数重载,运算符重载等等,这种重载一般都是在编译阶段时就已经确定了形态,这种多态,我们一般称之为静态多态,那么既然静态多态是在编译阶段就已经确定好了形态,那么动态多态,自然也就是在运行时才确定形态

请看如下代码:

现在调用Speak全局函数所得到的结果只会是动物在说话,为什么呢,因为这个全局函数在编译阶段时就已经通过函数参数确定了这是一个Animal类的Speak成员函数,那么我们想让猫传过去就调用猫的Speak,狗传入就调用狗的Speak,就需要用到关键字virtual,在Animal下的Speak函数前加上 此关键字,即可让此成员函数变为虚函数,我们也可以让Speak全局函数实现谁传入就调用谁的Speak,那么这一原理究竟是什么呢,下面我们来进行简单的剖析

首先我们借助visual studio的开发人员工具来帮助我们剖析,在vs的PowerShell下进入到源文件所属文件夹路径下,再输入 cl /d1 reportSingleClassLayout类名 + 源文件名后可以看到此类的所有属性

这是没有加virtual关键字的Animal:

仅显示了大小为1,因为这是个空类,空类的大小都为1,这是加了virtual关键字的Animal

 可以发现多了一个vfptr和vftable,vfptr:v指virtual,可以理解为虚的意思,f指functino,ptr自然就是pointer,意为虚函数指针,所指向的就是vftable,vftable意为虚函数表,里面存放着:&Adnimal::speak ,也就是虚函数的地址,我们再来看猫类不重写Speak函数的属性

 可以发现Cat类没有重写函数时的虚函数表中是通过Animal继承过来的Animal下的Speak函数地址,那重写后的为:

 可以发现,Cat重写Speak函数后,虚函数表内的函数地址由Animal的函数地址替换为了Cat的函数地址,所以我们在调用Speak全局函数时,只要Speak的函数参数通过& 来接收,甭管你什么类名,都是我Cat的别名,那我们现在Cat所指向的虚函数表中所记录的是我Cat的虚函数地址,跟你Animal就没有任何关系,所以就回调用Cat的Speak函数

简单总结一下,实现动态多态就是依靠虚函数,而虚函数内部又有虚函数指针和虚函数表,当继承者继承过去但没有发生重写虚函数时,内部所记录的就是父类的虚函数地址,一旦重写,就会将虚函数表中的父类地址给替换为自己的地址,使用时只要是使用子类对象时,不管如何将父类强加于身,我们所调用重写过的虚函数地址时都会是调用自己的函数地址,主要原因就是函数列表中的替换

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++多态----虚函数初级剖析 的相关文章

随机推荐

  • 几种C/C++语言安全检测工具介绍

    转自新浪微博http www vckbase com index php wv 1635 针对C C 语言安全漏洞的分析检测也出现了大量的工具 按照不同的机理主要分为以下几类 如表所示 分析类型 机理 分析工具 备注 静态分析 预处理 Fo
  • ## Hive分区、桶、与倾斜

    Hive的分区 1 在Hive Select 查询中一般会扫描整个表内容 会消耗很多时间做没必要的工作 有时候查询 只需要扫描表中关心的一部分数据 因此建表时引入partition概念 2 分区表指的是在创建表时指定的partition的分
  • 数据库查询最近N天数据

    查询最近7天数据 1 查询最近7天订单金额 用到了虚表和UNION ALL的知识 其中 price是要查询的数据 orders是表名 IFNULL b price 0 是指b price如果值为空 则将空值设置为0 SELECT a cli
  • Java版手写数字(0~9)BP神经网络识别

    MNIST的样本集太无趣 连图片都看不到 也无法用人手进行输入 所以 基于BP神经网络的理论知识 参见数据挖掘黑书212页起 讲得甚好 纯手写了一版带训练和测试的小玩具 Java语言 效果如下 代码已上传github https githu
  • 多项式回归(非线性回归)的python代码实现

    1 概述 在解决回归问题中 很多数据集中输入空间与输出空间并非完全呈线性关系 使用线性回归无法解决此类问题 为了解决存在非线性关系的数据集的回归问题 需要进行多项式回归 但sklearn并未提供多项式回归模型的类 多项式回归使用的还是线性回
  • 字节的对齐方式

    VC对结构的存储的特殊处理确实提高CPU存储变量的速度 但是有时候也带来了一些麻烦 我们也屏蔽掉变量默认的对齐方式 自己可以设定变量的对齐方式 重要规则 1 复杂类型中各个成员按照它们被声明的顺序在内存中顺序存储 第一个成员的地址和整个类型
  • 【k8s】k8s部署网络插件Calico、创建网络策略

    一 简介 01 calico简介 calico官网 flannel实现的是网络通信 calico的特性是在pod之间的隔离 通过BGP路由 但大规模端点的拓扑计算和收敛往往需要一定的时间和计算资源 纯三层的转发 中间没有任何的NAT和ove
  • String、StringBuffer与StringBuilder之间区别

    String StringBuffer StringBuilder String的值是不可变的 这就导致每次对String的操作都会生成新的String对象 不仅效率低下 而且浪费大量优先的内存空间 StringBuffer是可变类 和线程
  • Σ-Δ ADC的高精度数模转化,是如何实现的?

    以前接触过 ADC24位采样芯片 一直对其原理没有搞清楚 最近看到有对其原理讲解的文章 因此收集下来作为参考 我们在了解Delta Sigma ADC原理之前 先明确几个概念 1 量化噪声 下图中 蓝色斜线是连续的模拟信号 阶梯状波形是经过
  • Flask学习笔记_异步CMS(五)

    Flask学习笔记 异步CMS 五 1 环境 1 安装nvm 2 安装node 2 使用vue cli创建项目 3 安装相关插件 4 后台CMS开发 1 页面结构 1 app vue搭建结构 2 element icon组件的使用 3 ic
  • matlab rand randn 每次生成的随机数都一样的解决方案

    文章目录 问题说明 解决方案 例子 生成不重复的随机数 生成重复的随机数 结论 参考文献 问题说明 在Matlab应用中 我们经常需要用到随机数 比如rand randn 等函数 都是生成某一类随机数的函数 对于rand 函数来说 每一次启
  • HDR到底是什么?

    此文章转发自互联网 先感谢论坛好友 xiaoyuer520的耐心讲解及推荐这篇文章给我 我愿意分享给大家一起共同进步 谢谢 大家如果有像我一样的 看到文字多的帖子就看不下去 但又很想知道HDR是什么Dolby Vision和HDR10的区别
  • MySQL入门篇之Xtrabackup备份与恢复

    一 Xtrabackup介绍 MySQL冷备 mysqldump MySQL热拷贝都无法实现对数据库进行增量备份 在实际生产环境中增量备份是非常实用的 如果数据大于50G或100G 存储空间足够的情况下 可以每天进行完整备份 如果每天产生的
  • Vue2.7.14、vuecli@5.0.8 升级 vite@4.4.8

    项目背景 Vue2 7 14 vuecli 5 0 8 element ui 2 15 13 node14 18 3 本项目内部项目 不涉及CDN加速 vite安装 pnpm add vite 4 4 8 D 入口文件index html
  • Qt自定义窗口圆角

    Qt设置圆角 在Qt中一般设置窗口圆角有两种方式 QSS 通过paintEvent自绘窗口 QSS 设置圆角 这种设置圆角的方式相对来说比较灵活 但我们设置基类窗口 最外层窗口 用qss就很不方便 会收到后续qss的影响 另外当圆角设置大小
  • Docker 安装教程

    目录 一 离线安装 一 CentOS 离线安装 一 下载地址 1 选择系统的型号 选择linux CentOS 2 上传文件到CentOS 服务器 二 开始安装 1 解压压缩包 2 解压得到的文件复制到 usr bin目录下 3 注册doc
  • 想要好看的壁纸图片,用这个网站一键解决,不用爬虫也能实现爬虫效果,一键爬取图片网站所有的图片

    想要好看的壁纸图片 用这个网站一键解决 不用爬虫也能实现爬虫效果 一键爬取图片网站所有的图片 网站的地址 https extract pics 演示例子 图片网站 https www sohu com a 582693827 1211239
  • eclipse创建maven项目报Could not calculate build plan: Plugin org.apache.maven.plugins:maven-war-plugin:2.

    创建maven项目eclipse报下面错误 Could not calculate build plan Plugin org apache maven plugins maven war plugin 2 2 or one of its
  • 宋浩高等数学笔记(十二)无穷级数

    完结 宋浩笔记系列的最后一更 之后会出一些武忠祥老师的错题 笔记总结 10月份就要赶紧做真题了
  • C++多态----虚函数初级剖析

    多态说白了就是多种形态 在C 中不少的函数都可以实现多种形态 例如函数重载 运算符重载等等 这种重载一般都是在编译阶段时就已经确定了形态 这种多态 我们一般称之为静态多态 那么既然静态多态是在编译阶段就已经确定好了形态 那么动态多态 自然也