C++ 虚函数实现:虚函数表 虚表指针

多态的理解,虚函数表的理解 虚函数的函数本体放代码段,不占对象内存;但会给对象增加 1 个__vfptr虚表指针,这个指针占对象内存。一个对象最多只有一个虚表指针,哪怕有 N 个虚函数;全部虚函数地址存在虚表里。子类重写虚函数,是改写虚表里面保存的函数地址,不会新增__vfptr(单继承前提下)。override只是编译期语法检查,不会改变内存布局。补充:调试器看到两次__vfptr,只是 UI 重复展示,内存物理上就一份虚表指针。多重继承多个带虚函数父类,内存才会出现多个真实不同的 vfptr。 阅读详情

一个问题

构造函数,静态成员函数,内联函数能不能为virtual函数?

内联函数:编译时展开的,虚函数是为了实现多态,是动态行为,两者是矛盾的。内联函数展开就不存在了,也就不存在函数地址了,无法调用。
但是,由于inline只是向编译器建议,所以编译器不会让inline和virtual同时起作用,所以也不会报错。

构造函数:虚函数使用虚指针调用函数,调用构造函数之前没有构造完成,是没有虚指针的。另外虚函数是在基类指针中调用派生类函数的方式,构造函数不需要也不可能让你这样做。构造时已经知道了这个类的类型,这和虚函数向矛盾

静态成员函数:静态函数没有this指针,无法调用虚函数。另外静态函数属于类,不属于对象,也就不存在对象虚函数为基础的多态。


虚函数表——虚函数的实现方式

想要更加深入理解上面那个问题,需要知道虚函数在C++中的实现方式。

虚函数(Virtual Function)是通过一张虚函数表来实现的。简称为V-Table。在这个表中,主要是一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其真实反应实际的函数。这样,在有虚函数的类的实例中分配了指向这个表的指针的内存,所以,当用父类的指针来操作一个子类的时候,这张虚函数表就显得尤为重要了,它就像一个地图一样,指明了实际所应该调用的函数。 —–百度百科

来看一张图片,Class1的实体(对象)中开头是一个指向虚函数表的指针,虚函数表中寸有虚函数的函数指针。Class2类是Class类的子类,对vfunc2()进行了覆写(override),所以vfunc2在Class2中的地址被覆写。
这里写图片描述

我们可以用visual studio的调试功能做个试验

#include<iostream>

using namespace std;

class base_1
{
private:
public:
    virtual void func1A() { cout << "base1 A" << endl; }
    virtual void func1B() { cout << "base1 B" << endl; }
    virtual void func1C() { cout << "base1 C" << endl; }
};

class base_2
{
private:
public:
    virtual void func2A() { cout << "base2 A" << endl; }
    virtual void func2B() { cout << "base2 B" << endl; }
    virtual void func2C() { cout << "base2 C" << endl; }
};
class childTest:public base_1,public base_2
{
private:
public:
    virtual void func1A() { cout << "Child A" << endl; }
    virtual void func1B() { cout << "Child B" << endl; }
    virtual void func2C() { cout << "chind C" << endl; }
};

int main()
{
    base_1 test;
    childTest ctest;
}

运行后实体中数据如下

这里写图片描述

类的实体(对象)的开头有指向虚函数的指针,那么虚函数表究竟在哪里?

类的所有对象共用一张虚函数表。而虚函数表具体位置各个编译器实现不同,有兴趣可以看http://blog.chinaunix.net/uid-26611383-id-3772200.html

关于虚函数机制的更深的内容可以看RednaxelaFX大大在知乎上的这个回答,http://www.zhihu.com/question/27459122

在查询这些资料的时候,很多人都推荐一本书《Inside the C++ objective model 》,看来之后要补一补。

基于卷积神经网络的人脸识别算法 摘要:近年来,随着科学技术的不断发展,人脸识别技术日渐成熟,使得人脸识别技术的使用率不断增大。例如:门禁、ATM机、公安系统以及新兴起的人机交互等领域,都应用到了人脸识别系统。在人脸识别研究领域中,深度学习扮演着重要的角色。由于深度学习的人脸识别技术凭借其识别率高、识别快等特点,逐渐成为整个领域的主流技术。在众多深度学习算法中,以卷积神经网络为代表的人脸识别系统得到了广泛应用,主要研究内容如下:首先,通过对经典损失函数进行研究,对比每种损失函数的特点,然后根据A-Softmax函数进行改进,借助Margin 阅读详情

相关推荐

emqx Java 订阅以及发送 结合若依框架

emqx Java 订阅以及发送 结合若依框架

Spo的博客 1613

C++虚函数实现模拟

目录前言虚函数表分析虚函数模拟实现虚函数原理分析 前言 虚函数的实现包含两个重要部分,虚函数表和虚函数表指针。 虚函数表:一个类如果有虚函数,则针对这个类会产生一个虚函数表; 虚函数表属于类。 虚函数表指针:生成这个类的对象时,对象里就包含了一个指针(虚函数指针),用来指向这个虚函数表的起始地址; 虚函数表指针属于对象,一般位于对象内存的起始位置。 虚函数表分析 看如下示例代码(代码1),父类Base包含三个虚函数f、g、h,子类Derive重写了其中两个虚函数f、g: class Base { pub

kpengk的博客 382

从安装到出图:一份给振动测试新手的LMS Test.Lab 2021完整避坑手册(含许可证更新和常见弹窗解决)

本文为振动测试新手提供LMS Test.Lab 2021的完整使用指南,涵盖安装配置、许可证更新、数据采集到频域后处理的全流程。特别针对常见弹窗错误提供解决方案,并详细讲解Colormap时频图分析技巧,帮助用户快速掌握振动数据分析核心技能。

weixin_29268331的博客 981

C++中的虚函数(表)实现机制以及用C语言对其进行的模拟实现

前言C++对象的内存布局 只有数据成员的对象没有虚函数的对象拥有仅一个虚函数的对象拥有多个虚函数的对象单继承且本身不存在虚函数的继承类的内存布局本身不存在虚函数(不严谨)但存在基类虚函数覆盖的单继承类的内存布局定义了基类没有的虚函数的单继承的类对象布局多继承且存在虚函数覆盖同时又存在自身定义的虚函数的类对象布局如果第1个直接基类没有虚函数(表)What if 两个基类都没有虚函数表如果有三个

大自然的小女孩 1039

AlphaFold3实战:用它预测抗体结构,我的CDR H3环RMSD降到了2Å以内

本文详细介绍了如何利用AlphaFold3(AF3)高精度预测抗体结构,特别是CDR H3环的建模,其RMSD可降至2Å以内。通过实战演示从序列输入到结构优化的全流程,包括参数配置、置信度指标解读及结果分析,帮助研究人员快速掌握AF3在抗体药物研发中的应用。

weixin_29224529的博客 187

语音AI Agent落地实战:从ASR-NLP-TTS到多通道协同决策

语音AI Agent并非简单的自动语音识别(ASR)、自然语言处理(NLP)和文本转语音(TTS)三模块串联,而是在真实场景中需兼顾实时性、鲁棒性与隐私合规的端到端交互系统。其核心原理在于打破‘文本中间态’依赖,通过声学-文本-上下文多通道协同决策,融合原始音频特征、N-best置信度与设备环境信号,实现动态意图推演。技术价值体现在低延迟(如120ms离线唤醒)、高抗噪(-5dB SNR下WER≤25%)及强可控性(断网降级、本地热更新)。典型应用场景覆盖车载语音、智能家居与银行网点等边缘受限环境,尤其适用

weixin_29065959的博客 326

C++之深入解析虚函数表的实现及其内存布局

C++ 中的虚函数的作用主要是实现了多态的机制,关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数:Derive d;b1 -> f();这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术,就是试图使用不变的代码来实现可变的算法。比如:模板技术,RTTI 技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议。

╰つ栺尖篴夢ゞ 1513

主流反爬虫、反作弊防护与风控对抗手段

主流反爬虫、反作弊风控防护中的核心设计点与对抗策略

吴秋霖的博客 2554

C++中的虚函数(表)实现机制及模拟实现

前言 大家都应该知道C++的精髓是虚函数吧? 虚函数带来的好处就是: 可以定义一个基类的指针, 其指向一个继承类, 当通过基类的指针去调用函数时, 可以在运行时决定该调用基类的函数还是继承类的函数. 虚函数是实现多态(动态绑定)/接口函数的基础. 可以说: 没有虚函数, C++将变得一无是处! 既然是C++的精髓, 那么我们有必要了解一下她的实现方式吗? 有必要! 既然C++是从C语言的基础上发展而来的, 那么我们可以尝试用C语言来模拟实现吗? 有可能! 接下来, 就是我一步一步地来解析C++的虚函数的

zhipingxi的博客 580

40.8K星爆火!Crawl4AI实战突破Cloudflare 5秒盾:AI反爬新范式,爬虫再也不被封

Crawl4AI的爆火(40.8K星)不是偶然——它解决了爬虫工程师最头疼的反爬问题,让爬虫从“体力活”变成“脑力活”,不用再花费大量时间配置指纹、编写行为脚本。但要注意:爬虫必须遵守目标网站的robots.txt协议,不得用于非法爬取数据(比如用户隐私、商业机密)。合理使用技术,才能长久落地。如果你在使用Crawl4AI时遇到具体问题(比如绕过更严格的反爬、批量爬取配置),欢迎在评论区交流,我会第一时间分享解决方案!

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1603

Sigrity System Explorer ViaWizard模式进行过孔建模和仿真分析操作指导

点击TVac_lower tdvac_lower,自动跳转到2D时域曲线,查看最小低电平穿过VIL(ac)max电压的延时,结果如下。点击TVac_high tdvac_high,自动跳转到2D时域曲线,查看最小高电平穿过VIH(ac)min电压的延时,结果如下。点击max Vix_Rise,自动跳转到2D时域曲线,查看上升边PN交叉点与参考电压VREF(dc)的偏差,结果如下。Threshold:阈值,软件自带3个模板,default,Tr01,Tr02,本例选择Default。

weixin_54787054的博客 571

c语言 虚函数,C语言模拟虚函数表

使用C语言模拟虚函数表的实现。/* 模似的虚函数表* pVtable vtable* 接口指针 ---> 虚函数表指针 ---> 指针函数1 --->* 指针函数2 ---> 对象实现* ...

weixin_31659095的博客 626

【原理图PCB专题】Cadence17.4 PCB位号重排与反标

Cadence17.4 PCB位号重排与反标比Cadence16版本更简单一些,那到底如何操作?

一点硬件 1181

深入理解C++多态机制:虚函数、虚表与对象内存模型解析

本文深入探讨了C++多态的实现原理。多态通过虚函数机制实现"同一接口,不同行为",其核心在于虚函数表和动态绑定。文章详细分析了单继承、多继承及菱形继承下的虚函数表结构,比较了普通继承与虚继承的内存布局差异,并解释了虚基表指针的作用机制。通过买票案例展示了多态的实际应用,同时剖析了抽象类和纯虚函数的特性。最后,文章提供了查看虚函数表内容的实用方法,帮助读者直观理解多态在底层的实现方式。

2302_77620024的博客 2万+

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

C++中为什么要用虚函数、指针或引用才能实现多态?

学过C++的都知道,要实现C++的多态性必须要用到虚函数,并且还要使用引用或者指针,以前学习的时候书本上也是这么说, 但是书本上没有说为什么?   其实只要你认真思考过这个问题你会有三个疑问: 为什么要用虚函数? 为什么要用指针或者引用? 为什么使用派生类和基类对象之间直接赋值不能实现?? 一个简单的例子: [cpp] view pl

停止更新,迁移至ykpeng.com 1049

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

多态的实现原理分析----虚表

实现多态三点: 1.必须最少两个类,而且必须是继承 2.必须函数是虚函数(同名,同参,同返回类型) 3.通过基类的指针或引用来实现 一个类里边无论有多少个虚函数,虚表指针__vfptr只会有一个,占四个字节 虚表中有两部分内容:1、虚函数的地址;2、虚函数; #include&lt;iostream&gt; using namespace std; class Base { virt...

We_are_family678的博客 449

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Re:从零开始的 C++ 进阶篇(三)彻底搞懂 C++ 多态:虚函数、虚表与动态绑定的底层原理

摘要:本文系统解析C++多态机制的底层原理,重点探讨运行时多态的实现方式。通过虚函数和重写机制,结合基类指针/引用的动态绑定特性,实现同一行为在不同对象上的差异化表现。文章详细讲解虚函数重写的"三同"原则(函数名、参数列表、返回值相同),并通过经典面试题演示多态调用时的参数传递规则,揭示虚函数表在动态绑定中的关键作用。最后通过"买瓜"案例生动展示多态在实际编程中的应用场景,帮助读者深入理解这一面向对象编程的核心特性。

小此方的博客 1272

C++ 内存布局详解:类、虚函数、虚表底层原理

*C++ 的对象内存布局 = 成员变量 + 可能的虚表指针;虚函数多态 = 编译期生成虚表 + 运行期查表调用。**

2609_95039349的博客 173

C++多态:纯虚函数和抽象类和多态的原理

在虚函数的后面写上 = 0,则这个函数为纯虚函数,纯虚函数不需要定义实现(实现没啥意义,实例化不出对象,且要被派生类重写,但是语法上可以实现),只要声明即可。包含纯虚函数的类叫做抽象类,抽象类不能实例化出对象(但是可以定义它的指针,其指针可以指向派生类对象,以达到实现多态的目的),如果派生类继承后不重写纯虚函数,那么派生类也是抽象类。纯虚函数某种程度上强制了派生类重写虚函数,因为不重写实例化不出对象。

Jammy_1的博客 179

虚函数表深度终极剖析,虚表内存布局、单/多重/菱形继承虚表、虚调用汇编解析、多态底层完全解密

我们下沉到 CPU 与内存最底层,彻底吃透了C++ 内存对齐与结构体布局机制,掌握了结构体大小精准计算、内存填充冗余、位域压缩、强制对齐规范,解决了网络协议解析、内存池设计、性能优化中的各类内存布局疑难问题,搭建起完整的C++内存底层认知体系。今天我们攻克 C++最核心、最深层、面试必考的终极底层原理——虚函数表(VTable)。此前我们学习的多态、虚函数、重写,都只是表层语法使用,而虚表是运行时多态的唯一底层支撑。绝大多数开发者只会背诵“虚函数实现多态”,完全不知道。

2401_86195313的博客 311

C++多态

多态简单来说就是有多种形态,就是当你传入不同对象就会完成不同的行为。相当于就是你传入一个狗对象就是“汪汪汪”,当传入一个猫对象就是“喵喵喵”。

2301_80662872的博客 958

虚函数的机制

在C++中为了实现运行中的多态,需要满足三个条件:类之间是派生关系;声明基类、派生类的成员函数为虚函数;在满足赋值兼容性规则的前提下,通过指针或引用访问虚函数。虚函数的为了实现动态联编(运行多态)而引入的概念。 动态联编(dynamic binding)和静态联编(static binding)。静态联编意味着编译器能够直接将标识符和存储的物理地址联系在一起。每一个函数都有一个唯一的物理地址,当...

weixin_30894389的博客 79

c++的虚函数表(虚表)和虚基表

虚基表, 虚基表是对继承中的虚函数创造的,为了解决数据的冗余和二义性,将在继承的类中的内存值称为虚基表,虚基表中存放着偏移量,通过偏移量找到最初的数据,解决了数据的二义性。这个是虚函数表,简称虚表,是存放在代码段的,也就是常量区,存放的叫虚函数指针,虚函数也是放在代码段的,虚表指针才是存在类对象中的,虚函数表是存放虚函数的,里面包含的是继承下的虚函数,

z20050930的博客 62

【C++】透视C++多态:从虚函数表到底层内存布局的完全拆解

通过调试时我们发现似乎有些问题,理论上派生类d,应该会有三个虚函数(继承基类的两个,新增加的两个),但是我们发现虚表中只有两个指针,我们看不到Func3()和Func4(),这里是编译器隐藏了这两个函数,可以认为是VS的一个Bug。下面这段代码中,Buy()函数,如果传入的是Person调用的就是Person::BuyTicket(),传Student调用的是Student::BuyTicket。运行时决议,运行时才确定函数的地址。代码语言:javascript。代码语言:javascript。

m0_74824496的博客 140

C++ 多态完全指南:虚函数、重写、虚表与动态绑定深度解析

本文介绍了C++中的多态概念及其实现方式。多态分为编译时多态(静态多态)和运行时多态(动态多态),前者通过函数重载和模板实现,后者通过虚函数重写实现。通过示例代码展示了多态的实际应用场景和注意事项。

2402_90030627的博客 600

C++成员函数调用以及多态实现

C++支持三种类型的成员函数,分别为nostatic、static、virtual,每一种调用方式都不相同。 非静态成员函数(Nonstatic Menber Function) 改写成员成员函数签名,使其可以接收一个额外参数,这个参数是this指针 int Point::func(); //被改写为 int Point::func(Point* this);//如果成员函数是const的,插...

越丘的博客 1512
下一篇: Leetcode#217 Contains Duplicate $hash
Tommylwp
博客等级 码龄12年 11粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值