【C++ 多态】带你详细了解虚函数表

news2024/11/19 1:52:11

文章目录

      • 1.一道面试题 -- 引入虚函数表
      • 2.多态是怎么实现的呢?
        • 2.1满足多态的时候🐧
        • 2.2不满足多态的时候🐧
      • 3.打印虚函数表

1.一道面试题 – 引入虚函数表

①🍎 _vfptr 虚表指针,虚表指针是用来实现多态的 多态的原理

对象中的这个指针我们叫做虚函数表指针(v代表virtual,f代表function)。一个含有虚函数的类中都至少都有一个虚函数表指针,因为虚函数的地址要被放到虚函数表中,虚函数表也简称虚表;

②🍎 这里常考一道笔试题:sizeof(Base)是多少? (8个字节

在这里插入图片描述

2.多态是怎么实现的呢?

2.1满足多态的时候🐧

①🐧满足多态的时候,程序运行时才会去虚函数表中找对应的虚函数调用,指向父类调父类,指向子类调子类;

运行时PersonStudent 不同类型都有不同的虚表,同类型的虚表相同;

在这里插入图片描述


②🐧重写这个概念进一步了解:
基类b对象和派生类d对象虚表是不一样的,这里我们发现Func1完成了重写,所以d的虚表中存的是重写的Derive::Func1,所以虚函数的重写也叫作覆盖,覆盖就是指虚表中虚函数的覆盖。重写是语法的叫法,覆盖是原理层的叫法。
在这里插入图片描述

③🐧派生类的虚表生辰过程:
🍎a.先将基类中的虚表内容拷贝一份到派生类虚表中;
🍎b.如果派生类重写了基类中某个虚函数,用派生类自己的虚函数覆盖虚表中基类的虚函数 ;
🍎c.派生类自己新增加的虚函数按其在派生类中的声明次序增加到派生类虚表的最后;

2.2不满足多态的时候🐧

①🐧不满足多态的时候,就不能达到指向谁调用谁,在编译的时候,就根据对象的类型进行调用了;
在这里插入图片描述

3.打印虚函数表

易错点❗❗❗:
①🐧只有相近的数据类型才能转换 (不可以从自定义类型强制转换成为整形);

#include <iostream>

using namespace std;


class Base {
public:
	virtual void func1() { cout << "Base::func1" << endl; }
	virtual void func2() { cout << "Base::func2" << endl; }
private:
	int a = 1;
};

class Derive :public Base {
public:
	virtual void func1() { cout << "Derive::func1" << endl; }
	virtual void func3() { cout << "Derive::func3" << endl; }
	virtual void func4() { cout << "Derive::func4" << endl; }
private:
	int b = 2;
};

// 打印对象虚表
typedef void(*VFPTR)();

// 打印函数指针数组
// virtual function table
//void PrintVFT(VFPTR vft[])
void PrintVFT(VFPTR* vft)
{
	for (size_t i = 0; i < 4; i++)
	{
		printf("%p->", vft[i]);

		VFPTR pf = vft[i];
		(*pf)();
		//pf();
	}
}

int main()
{
	Base b;
	Derive d;

	//int ptr = (int)d; // 不支持转换,只有有关联的类型才能互相转

	//注意:地址也可以理解成为数据
	VFPTR* ptr = (VFPTR*)(*((int*)&d));
	PrintVFT(ptr);

	// 函数指针
	void (*p1)();
	VFPTR p2;

	// 函数指针数组
	void (*pa1[10])();
	VFPTR pa2[10];


	return 0;
}

在这里插入图片描述

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

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

相关文章

xgp怎么取消续费 微软商店xgp会员取消自动续费详细教程

xgp怎么取消续费 微软商店xgp会员取消自动续费详细教程 XGP这个游戏平台小伙伴们并不陌生吧&#xff0c;它是微软Xbox游戏部门推出的游戏租赁制会员服务&#xff0c;主要用于主机和PC两个平台。这个平台的会员就可以免费享受多款大制作游戏&#xff0c;而且每个月还会自动更新…

笔记 | 编译原理L2:词法分析(lexical analysis)

1 概述 词法分析(lexical analysis)&#xff0c;也称scanning, 编译程序的第一阶段,其作用是识别单词(程序意义上)并找出词法错误. 读入源程序的输入字符、将它们拆分成词素&#xff0c;生成并输出一个词法单元序列&#xff0c;每个词法单元对应于一个词素 回顾词法分析在整个…

jpa分页插件对象Pageable出现了错误异常如何解决?

jpa分页插件对象Pageable出现了错误异常如何解决&#xff1f;&#xff01; 一般来说&#xff0c;遇到这种的错误异常情况&#xff0c;通常情况 下&#xff0c;都是因为程序员把传递的分页页码数字写错了。 正常情况下&#xff0c;分页页码起始数字应该是0&#xff1b;而不是1…

OpenCASCADE(OCC)读入含中文汉字标签的内容后乱码的解决方法

笔者在导入一个由SolidWorks生成的step文件的时候&#xff0c;节点名称是中文&#xff0c;于是乎生成的节点树的名称都是乱码了&#xff0c;经过多次的排查调研&#xff0c;最后的解决办法如下&#xff1a; 1.老版本的occ库&#xff0c;是无法兼容读入中文编码的step文件的&am…

Linux 学习之路 -- 进程篇 -- 进程控制

目录 一、进程终止 <1>使用语言和系统自带的方法&#xff0c;进行转换 <2>自定义错误码 <3>小结&#xff1a; <2>两个接口exit / _exit 二、进程等待 <1>简单了解 <2>wait调用 <3>waitpid调用 <4>status <1>W…

Laravel 6 - 第十四章 响应

​ 文章目录 Laravel 6 - 第一章 简介 Laravel 6 - 第二章 项目搭建 Laravel 6 - 第三章 文件夹结构 Laravel 6 - 第四章 生命周期 Laravel 6 - 第五章 控制反转和依赖注入 Laravel 6 - 第六章 服务容器 Laravel 6 - 第七章 服务提供者 Laravel 6 - 第八章 门面 Laravel 6 - …

debian配置distcc分布式编译

前言 distcc 是一个用于在网络上的多台机器上分发 C、C、Objective C 或 Objective C 代码构建的程序。 distcc 应始终生成与本地构建相同的结果&#xff0c;易于安装和使用&#xff0c;并且通常比本地编译快得多。 distcc 不要求所有机器共享文件系统、同步时钟或安装相同的…

【目录】Armv8/Armv9付费专栏

快速链接: . &#x1f449;&#x1f449;&#x1f449; ARMv8/ARMv9架构入门到精通-[目录] &#x1f448;&#x1f448;&#x1f448; 付费专栏-付费课程 【购买须知】:联系方式-加入交流群 ----联系方式-加入交流群 个人博客笔记导读目录(全部) 目录 【Arm基础】【指令和寄…

在AI工业变革的拐点,迎来AI智算“安卓时刻”

今天&#xff0c;我们正在进入AI的工业变革拐点期。所谓AI的工业变革&#xff0c;主要指以大模型AI所引发的通用AI和以通用AI为目标构建的工业标准化AI智算基础设施。 在通用计算时代&#xff0c;X86所代表的工业标准化技术体系造就了企业IT、互联网与云数据中心。而在智算时代…

Mysql索引详解(索引分类)

文章目录 概述索引对查询速度的影响索引的优缺点索引类型一级索引和二级索引的区别MySQL 回表联合索引&#xff08;最左前缀原则主键索引和唯一索引的区别BTree索引和Hash索引的区别 覆盖索引索引下推加索引能够提升查询效率原因MySQL 索引结构采用 B树原因索引失效的场景MySQL…

油管评论抓取软件,专为文科生、小白用户开发!

我用Python开发的youtube评论采集软件&#xff0c;爬取到的字段包含&#xff1a; 评论id、评论内容、评论时间、评论作者昵称、评论作者频道、点赞数 软件界面效果&#xff1a; 采集结果数据&#xff1a; 软件使用注意事项&#xff1a; 详细讲解文章&#xff1a; https://…

1-35 集合框架

一 集合的介绍 1.集合是 Java 提出用来进行多个数据存储的 "容器" , 那数组同样具备这样的功能 , 为什么还要有集合 , 数组一旦创建长度固定 , 只能存放一种数据类型 , 不够灵活,因此 Java提出更灵活的操作 , 存放任意引用数据类型 的 容器 -- 集合 2.分类 ①单列…

变电站的组成、作用及功能

变电站的组成、作用及功能 变电站是电力系统的重要组成部分&#xff0c;主要用于实现电力输送、配电和转换的功能。它是将高压电力系统变成低压电力系统的中间站点&#xff0c;它可以将高压输电线路传输的电能通过变压器进行调整&#xff0c;将电能变成适应于城市、乡村和工矿企…

STM32F103单片机C语言模块化编程实战:按键控制LED灯并串口打印详解与示例

一、开发环境 硬件&#xff1a;正点原子 STM32F1精英版 开发板 单片机&#xff1a;STM32F103ZET6 Keil版本&#xff1a;5.32 STM32CubeMX版本&#xff1a;6.9.2 STM32Cube MCU Packges版本&#xff1a;STM32F1 V1.8.5 虽然这里演示的是STM32F103&#xff0c;但是STM32F40…

STM32cubemx和HAL库的使用入门--点亮一颗LED

一&#xff1a;流程介绍 &#xff08;1&#xff09;环境搭建 1 &#xff1a;stm32cubemx安装 2 &#xff1a;stm32xxFW安装 3 &#xff1a;MDK5安装 4 &#xff1a;生成MDK版本project &#xff08;2&#xff09;stm32cubemx创建工程&#xff0c;选择芯片型…

Python中pyside2出现的pyside2 qt platform plugin could be in错误及其解决方法

系统平台&#xff1a;Win10 64bit python版本&#xff1a; python 3.8 使用pip install pyside2安装 pyside2 这是找不到QT平台的插件&#xff0c;这是环境变量QT_QPA_PLATFORM_PLUGIN_PATH出现错误 具体解决方法&#xff1a; 我们可以在每一段程序开始之前设定环境变量&…

Shader实战(3):贴图像素化风格实现

话不多说&#xff0c;将以下shader赋给材质贴上贴图即可。 Shader "HQY/Shader2" //自己改名 {Properties{_Diffuse ("Diffuse", Color) (1,1,1,1)_MainTex ("MainTex", 2D) "white" {}_Specular("Specular", Color) (…

JavaScript 数学对象 Math

Math对象其实就是数学对象&#xff0c;它给我们提供了各种各样的数学功能。 <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>首页</title> </head><body><script type"text/javascript"&g…

1.3 初探Spring AOP

本次课&#xff0c;我们深入了解了Spring框架中的AOP&#xff08;面向切面编程&#xff09;概念&#xff0c;它是一种编程范式&#xff0c;用于处理那些在多个类中重复出现、与业务逻辑无关的横切关注点&#xff0c;如日志记录、事务管理等。AOP与OOP&#xff08;面向对象编程&…

【Linux系列】 离线安装vnc 可视化桌面

离线安装vnc 可视化桌面 缘下载安装vnc初始化链接 缘 项目需要下载 下载地址&#xff1a; http://mirror.centos.org/centos/7/updates/x86_64/Packages/tigervnc-license-1.8.0-31.el7_9.noarch.rpm http://mirror.centos.org/centos/7/os/x86_64/Packages/libXfont2-2.0.…