中有atoi函数吗_C++ 多态的实现及原理,深挖vptr指针,手动调用虚函数

什么是多态?

 父类指针即根据指向的不同对象,响应同一消息(函数调用),产生不同行为。

多态三要素?

1,继承

2,虚函数重写

3,父类指针(引用)指向子类对象

多态的实现很简答,让我们来看一段代码

#includeusing namespace std;class Parent{public:  virtual void show(){    cout << "我是你爹" << endl;  }};class Child:public Parent//1,继承{public:  virtual void show()//2,虚函数重写{    cout << "我是你崽" << endl;  }};int main(){  Parent *pa = new Child;//3,父类指针指向子类对象  pa->show();  getchar();  return 0;}//结果输出的是子类的show函数--"我是你崽"

实现很简单,但是这又是什么原理呢?

当我们在类中声明了虚函数之后,编译器会给类添加一个vptr指针,当定义对象的时候,会把所有虚函数放入一个叫虚函数表的顺序表,然后用vptr指针指向虚函数表。当进行pa->show();调用的时候,C++编译器不需要区分子类或者父类对象,只需要在pa指针中,找到vptr指针即可。

如果对象类型是子类,就调用子类的函数;如果对象类型是父类,就调用父类的函数,(即指向父类调父类,指向子类调子类)此为多态的表现。

既然类里面有vptr指针,那么我们能找到它吗?

咱们一起来探究下:首先看下加了虚函数的类的大小有没有变化。

215a28f82e7397ab6a5583cc19d89289.png

可以看到加了虚函数,类的大小比没有增加虚函数的类,多了四个字节的空间,有的同学可能会说,四个字节的类型不一定是指针。不要着急,让我们继续往下看。

接下来我们定义对象,然后通过调试,看下局部变量窗口

5738b7c2b09d5a52aada540e45fc37e4.png

从这里就可以明确看到,子类对象中有一个vptr指针,而且它是对象的第一个成员,它的类型是void**,指向的是一个顺序表,下标为0的元素装的是我们声明的虚函数。

那么,知道了这些,咱们能利用对象找到虚函数表,然后自己手动调用虚函数吗?

你们:肯定可以啊,废话

我:。。。那就废话不多说,欧力给!搞起

我:首先画一张内存模型图,瞅瞅(画工太丑,见谅)

37177008081ae0bffe5cc15a5d505356.png

1,首先,要拿到vptr指针,怎么拿呢?因为它在对象的第一个元素,所以我们先对对象取地址&ch,这样就拿到了对象的地址。对象的元素的内存是连续的,但是现在指针的步长是Child类的大小,我们需要把它当成一个整型数组(因为vptr是四个字节),所以需要强转成int*,即(int*)&ch,这样之后数组第一个元素就是vptr指针了,取值即可得到

*(int*)&ch

2,然后,前面通过调试我们知道了,vptr指针是void**类型的,所以我们也要讲它转为int*,然后取值.*(int*)(*(int*)&ch),这样就拿到了虚函数表的第一个元素。

3,但是,现在拿到的元素是int*型,不是函数指针,无法调用,所以我们需要强转为函数指针,才能进行调用。

640d749ecf11ae1e989c04f8474f2595.png

你学废了没?嘿嘿

455fc44e5281fd875e3e0da51824e85e.png

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

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

相关文章

一文带你读懂base64编码

hi&#xff0c;大家好&#xff0c;我是开发者FTD。相信很多同学在工作中&#xff0c;经常会用到Base64编码&#xff0c;那大家知道为什么会有Base64编码吗&#xff1f;我们为什么要使用它呢&#xff0c;它又是怎么实现的呢&#xff1f;下面就让我们来一起深入探究一下Base64编码…

不显示参数名_第51p,万能参数与返回值,Python中函数的返回值

大家好&#xff0c;我是杨数Tos&#xff0c;这是《从零基础到大神》系列课程的第51篇文章&#xff0c;第三阶段的课程&#xff1a;Python进阶知识&#xff1a;详细讲解Python中的函数&#xff08;四&#xff09;>函数的参数与返回值&#xff08;下篇&#xff09;。函数是非常…

阿里云服务器安装JDK指南

hi&#xff0c;大家好啊&#xff0c;好久不见&#xff0c;最近阿里云双十一做活动&#xff0c;很多博主都在做购买返现活动&#xff0c;不知道大家有没有去白嫖他们一个服务器&#xff0c;服务器买来可以用来学习一下服务器搭建&#xff0c;应用部署等等&#xff0c;可以做的事…

销售流程图_工作流程图网络图模板,招聘销售合同库存,完整设计拿来就用

Hello大家好&#xff0c;我是帮帮。今天跟大家分享一组工作流程图模板&#xff0c;招聘销售合同库存&#xff0c;完整设计拿来就用。为了让大家能更稳定的下载模板&#xff0c;我们又开通了全新下载方式(见文章末尾)&#xff0c;以便大家可以轻松获得免费模板和收费模板。メ大家…

协议详解_I2C协议详解

I2C通信协议I2C通信协议的基础简介I2C「Inter-integrated Circuit」总线支持设备之间的短距离通信&#xff0c;用于处理器和一些外围设备之间的接口&#xff0c;它只需要两根信号线来完成信息交换。I2C最早是飞利浦在1982年开发设计。I2C是同步传输信号&#xff0c;关于同步和异…

http 302错误_http面试题

作者&#xff1a;忘れられたくない出自&#xff1a;SegmentFault 思否原文&#xff1a;segmentfault.com/a/1190000024538846http状态码分类1xx服务器收到请求2xx请求成功3xx重定向4xx客户端错误5xx服务端错误常见状态码200 成功301 永久重定向302 临时重定向304资源未被修改40…

controller属于哪一层_孺教网分享|家长层次有五层,家长们都来看看,你属于哪一层?...

经常听到这样一些话&#xff1a;养不教父之过&#xff0c;有其父必有其子。孩子是父母的影子&#xff0c;父母是孩子的第一任老师.......这些都反映了在孩子成长的过程中&#xff0c;家庭教育的重要性。而家庭教育往往体现在非智力因素方面&#xff0c;比如感恩、诚信、善良、尊…

cad里面f命令用不了_CAD出现命令无效、失灵等问题?不用慌,两招帮你快速解决...

一、CAD常见无效问题1、填充命令无效我们有时候需要对某一区域进行填充&#xff0c;但是却发现怎么也填充不出来&#xff0c;这个时候就应该检查一下【选项】设置了&#xff0c;具体操作步骤如下&#xff1a;①命令行中输入【OP】&#xff0c;按下回车键调出【选项】对话框&…

卫生纸玫瑰花折法5步_餐巾纸折纸玫瑰花的折法图解教程

餐巾纸折纸玫瑰花的折法图解教程折纸玫瑰花的制作方法非常的多&#xff0c;但是常见的折纸玫瑰花制作方法基本上都是以方形纸张进行折叠来制作而成的。这里介绍的这种折纸玫瑰的制作方法更加的简单、经济和环保一些。同时其有着一个极大的优点&#xff0c;那就是无论在哪里都可…

mysql status_mysql status查看

总结了几种查看MySQL运行状况的方法&#xff0c;如下&#xff1a;1、phpMyAdmin最简单的方式&#xff0c;在phpMyAdmin直接点击状态查看&#xff0c;详细如下图。这查看的是MySQL的一些运行状况数值&#xff0c;这种方式被大多数系统管理员所不齿&#xff0c;因为专业的MySQL服…

windows mysql 备份_Windows下MySQL数据库备份脚本(二) | 系统运维

说明&#xff1a;MySQL数据库安装目录&#xff1a;C:\Program Files\MySQL\MySQL Server 5.0MySQL数据库存放目录&#xff1a;C:\Program Files\MySQL\MySQL Server 5.0\dataMySQL数据库备份目录&#xff1a;D:\MySQLdata_Bak实现目的&#xff1a;备份MySQL数据库存放目录中的m…

mysql8解决区分大小写问题_球磨机“包球”和“饱磨”分不清?点进来快速区分,解决问题...

球磨机的“包球”和“饱磨”现象都是设备在磨矿过程中出现的常见故障&#xff0c;大多数用户对这两种情况不是特别了解&#xff0c;出现问题时也不知从何下手&#xff0c;导致机器无法正常作业。其实“包球”和“饱磨”有一定的相似之处&#xff0c;同时在产生原因、处理方法等…

控制浏览器增加新页签的js_技术网站重写复制按键 js 跳转到注册页,就能增加用户?...

背景技术网站重写复制按键的 js &#xff0c;作为开发人员你会为了复制一段代码而注册一个用户吗&#xff1f;一个小需求变动&#xff0c;将跳转详情页改为 target_blank 的方式打开新页面。原来用 Vue.js 的路由代码 push 需要换成 resolve &#xff0c;本文将介绍该需求调整过…

win7系统一直反复重启_iPhone7开机白苹果反复重启进不了系统维修过程

故障现象iPhone7开机时在出现苹果图标后反复重启&#xff0c;无法进入系统。维修过程拿到手机之后开机测试&#xff0c;在显示苹果图标界面反复重启。这种故障是开机过程不能通过自检造成的。由于客户要保留资料&#xff0c;所以是不能刷机。根据经验判断应该是基带部分有问题。…

mysql去掉小数点多余0_mysql数据库个性化需求:版本号排序

概述今天主要介绍一个MySQL数据库版本号排序问题&#xff0c;一起来看看吧~需求按版本号排序&#xff0c;版本号字段为字符类型&#xff0c;其中1.2.10应大于1.2.9&#xff0c;但mysql数据库会认为1.2.9大于1.2.1正确的版本号应该是 1.3.0 大于 1.2.231.2.10 大于 1.2.9实现sql…

mysql语句在哪编写_mysql常见问题七:编写sql语句

一、删除除了学号字段以外&#xff0c;其它字段都相同的冗余记录&#xff0c;只保留一条&#xff01;(也就是要删除凤姐和田七中一条重复数据只留一条)要求结果数据&#xff1a;原始数据&#xff1a;CREATE TABLEtbl_students (idint NOT NULL,namevarchar(10) DEFAULT NULL,sa…

sum()转字符串_Python字符串与内置函数

字符串创建变量来保存字符串 字符串可以通过单、双、三引号创建字符串message "Hello,world"#变量mseeage,值为hello,worldprint(message)输出结果&#xff1a;Hello,worldPython3,有3种数值类型分别为&#xff1a;int(整形)#创建变量为a,值为496a 496 #type查看类…

obj文件编辑软件_工程动画制作 | MAX文件导出obj、fbx格式在Bentley软件中应用

一、利用3dmax打开max模型&#xff0c;利用材质球吸取材质。看材质是否为标准材质(standard)&#xff0c;如若是&#xff0c;继续下一步操作。如若不是&#xff0c;修改材质球属性&#xff0c;保留贴图为子材质&#xff0c;更改为标准材质。二、处理模型面数、点数问题。利用修…

python 安装pandas 权限不够_详解Python学习之安装pandas

一、python pip的安装与使用1、pip 是 python 包管理工具&#xff0c;该工具提供了对python 包的查找、下载、安装、卸载的功能。目前如果你在 python.org 下载最新版本的安装包&#xff0c;则是已经自带了该工具。python 2.7.9 或 python 3.4 以上版本都自带 pip 工具。pip 官…

java的类是什么_java类是什么意思

java类就是具备某些共同特征的实体的集合&#xff0c;它是一种抽象的数据类型&#xff0c;它是对所具有相同特征实体的抽象。在面向对象的程序设计语言中&#xff0c;类是对一类“事物”的属性与行为的抽象。举一个例子说明下类&#xff0c;比如Person(人)就是一个类&#xff0…