全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

c++中的虚拟继承(virtual inheritance)实现原理_c++菱形继承的vtable布局【底层】

虚拟继承确保菱形继承中虚基类子对象唯一存在,由最派生类统一构造并置于对象末尾,通过vbptr和vbase table在运行时动态定位。

虚拟继承解决的是菱形继承中基类重复实例化的问题,其核心在于让最派生类“独占”一份虚基类子对象,并通过额外的指针(virtual base pointer, vbptr)和偏移信息(virtual base offset)在运行时动态定位虚基类成员。

虚基类子对象只存在一份

在非虚拟继承的菱形结构中(如 B 和 C 都继承 A,D 继承 B 和 C),D 对象内存里会包含两份 A 的副本。虚拟继承后,B 和 C 中对 A 的继承声明为 virtual,此时编译器确保 D 中仅存在**唯一一份 A 的子对象**,且它被放置在 D 对象布局的末尾(或靠近末尾)区域,而非嵌入在 B 或 C 子对象内部。

这意味着:

  • B 和 C 子对象内部不再包含 A 的数据成员,只保留一个 vbptr(指向虚基类表 vbase table)
  • D 的构造函数负责构造唯一的 A 实例,并调整所有中间类(B/C)中的 vbptr,使其能正确定位到该 A 实例
  • 访问 A 的成员时,需通过 vbptr + 偏移量间接计算地址,无法在编译期直接确定

vtable 中新增虚基类表指针(vbptr)和虚基类表(vbase table)

每个含虚基类的类(如 B、C)的对象头部(或特定位置)会多出一个指针:vbptr。它指向一张只读的虚基类表(vbase table),该表按虚基类声明顺序存放若干 偏移量(offset to virtual base)。

例如:

  • 假设 class B : virtual A,则 B 的 vbase table 第一项是 “从 B 对象地址到 A 子对象的字节偏移”
  • class D : B, C,D 的对象中,B 子对象和 C 子对象各自带自己的 vbptr;两者指向的 vbase table 内容可能不同,但最终都导向同一份 A 实例
  • 这个偏移值在 D 构造时由编译器生成并填入——因为只有最派生类知道 A 究竟被放在哪

构造顺序与偏移修正由最派生类控制

虚基类 A 的构造由最派生类 D 的构造函数**直接调用**(跳过 B 和 C 的构造函数中对 A 的调用),这是关键语义规则。同时,D 的构造函数体执行前,会先完成:

  • 为 A 分配空间(在 D 对象内某处)
  • 计算 A 相对于 B 子对象起始地址的偏移,并写入 B 的 vbptr 所指的 vbase table 对应项
  • 同理处理 C 的 vbptr

因此,B::func() 中若访问 A::x,实际执行的是:读 B->vbptr → 查 vbase table 得 offset → (char*)this + offset → 访问 x。整个过程比普通继承多一次查表+地址计算,有轻微开销。

典型 vtable / 对象布局示意(简化)

以 GCC/Itanium ABI 为例,D 对象内存大致如下(低地址→高地址):

  • [B 子对象]:vptr_B(指向 B 的 vtable)、B 自有成员、vbptr_B(指向 B 的 vbase table)
  • [C 子对象]:vptr_C、C 自有成员、vbptr_C
  • [A 子对象]:A 的数据成员(唯一一份)

B 的 vtable 除普通虚函数外,还隐含一个“虚基类偏移字段”,但更常见的是:vtable 末尾或单独存 vbase table,其中条目为 相对于当前子对象起始地址的偏移。比如 vbptr_B 指向的表中存着 +24,表示 A 子对象起始地址 = (char*)&b_obj + 24。

基本上就这些。虚拟继承不是语法糖,它改变了对象布局模型,引入了运行时间接寻址,但也换来语义上的唯一性和可预测性。理解它,关键是抓住“最派生类统一安置 + vbptr 动态导航”这一机制。


# 字节  # c++  # 构造函数  # char  # 指针  # 继承  # 虚函数  # class  # pointer  # 对象  # this  # table  # 的是  # 派生类  # 相对于  # 唯一一  # 中对  # 自己的  # 这是  # 这一  # 偏移量  # 放在 


相关文章: 深圳企业网站制作设计,在深圳如何网上全流程注册公司?  如何高效配置香港服务器实现快速建站?  可靠的网站设计制作软件,做网站设计需要什么样的电脑配置?  企业网站制作费用多少,企业网站空间一般需要多大,费用是多少?  制作假网页,招聘网的薪资待遇,会有靠谱的吗?一面试又各种折扣?  如何获取开源自助建站系统免费下载链接?  制作网站的基本流程,设计网站的软件是什么?  沈阳制作网站公司排名,沈阳装饰协会官方网站?  广州营销型建站服务商推荐:技术优势与SEO优化解析  北京制作网站的公司排名,北京三快科技有限公司是做什么?北京三快科技?  学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?  保定网站制作方案定制,保定招聘的渠道有哪些?找工作的人一般都去哪里看招聘信息?  制作国外网站的软件,国外有哪些比较优质的网站推荐?  建站之星安装后如何自定义网站颜色与字体?  网站制作和推广的区别,想自己建立一个网站做推广,有什么快捷方法马上做好一个网站?  安徽网站建设与外贸建站服务专业定制方案  小米网站链接制作教程,请问miui新增网页链接调用服务有什么用啊?  如何在宝塔面板中创建新站点?  实例解析Array和String方法  如何在IIS中新建站点并配置端口与IP地址?  太平洋网站制作公司,网络用语太平洋是什么意思?  如何通过wdcp面板快速创建网站?  如何配置FTP站点权限与安全设置?  如何登录建站主机?访问步骤全解析  ,如何利用word制作宣传手册?  测试制作网站有哪些,测试性取向的权威测试或者网站?  攀枝花网站建设,攀枝花营业执照网上怎么年审?  内部网站制作流程,如何建立公司内部网站?  公司网站制作需要多少钱,找人做公司网站需要多少钱?  如何通过NAT技术实现内网高效建站?  建站中国官网:模板定制+SEO优化+建站流程一站式指南  相亲简历制作网站推荐大全,新相亲大会主持人小萍萍资料?  制作网页的网站有哪些,电脑上怎么做网页?  孙琪峥织梦建站教程如何优化数据库安全?  手机怎么制作网站教程步骤,手机怎么做自己的网页链接?  黑客入侵网站服务器的常见手法有哪些?  义乌企业网站制作公司,请问义乌比较好的批发小商品的网站是什么?  如何用狗爹虚拟主机快速搭建网站?  制作网站的软件下载免费,今日头条开宝箱老是需要下载怎么回事?  rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted  实例解析angularjs的filter过滤器  免费ppt制作网站,有没有值得推荐的免费PPT网站?  东莞专业网站制作公司有哪些,东莞招聘网站哪个好?  微信小程序 input输入框控件详解及实例(多种示例)  ,在苏州找工作,上哪个网站比较好?  网站制作话术技巧,网站推广做的好怎么话术?  网站制作需要会哪些技术,建立一个网站要花费多少?  北京网站制作公司哪家好一点,北京租房网站有哪些?  jQuery 常见小例汇总  兔展官网 在线制作,怎样制作微信请帖? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。