当前位置: 首页 > news >正文

C++对象模型一图通:虚函数 vs 虚继承(vptr / vbptr 全部讲透)

一句话核心总结

虚函数:解决“调用哪个函数”(多态)
虚继承:解决“数据保留几份”(菱形继承)

👉 本质统一:

都是通过“指针间接层”来解决问题

一、虚函数(virtual function)

解决什么问题?

👉运行时多态(动态绑定)

示例

class Base { public: virtual void show() { std::cout << "Base\n"; } }; class Derived : public Base { public: void show() override { std::cout << "Derived\n"; } }; Base* p = new Derived(); p->show(); // 👉 输出 Derived

底层原理

对象中隐藏一个指针:

vptr(虚函数指针)

结构:

对象: [ vptr ] → vtable(虚函数表) [ 成员变量... ]

调用流程

p->show() → 找 vptr → 找 vtable → 找函数地址 → 调用

本质总结

虚函数 = 用 vptr 找函数地址,实现运行时多态

二、虚继承(virtual inheritance)

解决什么问题?

👉菱形继承中的数据重复问题

菱形继承问题

class A { public: int x; }; class B : public A {}; class C : public A {}; class D : public B, public C {};

问题

D d; d.x; // ❌ 二义性

👉 因为:

D 中有两份 A: B::A::x C::A::x

三、虚继承登场

class B : virtual public A {}; class C : virtual public A {};

✅ 结果

D 中只有一份 A

四、vbptr 是什么?

定义

vbptr = virtual base pointer(虚基类指针)

作用

用来找到“虚基类 A 在内存中的位置”

内存结构(核心)

D: ├─ B部分 │ └─ vbptr → 虚基类表(记录 A 偏移) │ ├─ C部分 │ └─ vbptr → 虚基类表(记录 A 偏移) │ └─ A(唯一一份) └─ x

访问流程

d.B::x

实际:

1. 进入 B 2. 找 vbptr 3. 查表 → 得到 A 的位置 4. 跳到 A 5. 访问 x

五、关键结论(必须记住)

虚继承不是“复制 A” 而是“共享 A”

本质一句话

B 和 C 并不拥有 A 而是共同指向同一份 A

六、vptr vs vbptr 对比

对比vptrvbptr
全称virtual table pointervirtual base pointer
作用找函数找数据
解决问题多态菱形继承
指向vtable虚基类偏移表
是否常用高频较少

路径对比

虚函数

对象 → vptr → vtable → 函数

虚继承

对象 → vbptr → 偏移表 → A → 数据

七、统一理解(架构级)

C++对象模型的核心思想: 通过“指针间接层” 来解耦结构与行为

三大核心指针

this → 当前对象 vptr → 找函数(多态) vbptr → 找数据(虚继承)

八、常见误区

❌ 误区1

virtual 是一个东西

👉 ❌ 错:

virtual function ≠ virtual inheritance

❌ 误区2

虚继承和多态有关

👉 ❌ 完全无关


❌ 误区3

vbptr 指向 A

👉 ❌ 错:

vbptr → 指向“偏移表” → 表里记录 A 的位置

九、工程建议

✅ 虚函数

  • ✔ 高频使用
  • ✔ 面向接口 / 多态设计

⚠️ 虚继承

  • ⚠ 只在菱形继承使用
  • ⚠ 会增加对象复杂度

最终总结

虚函数: → 用 vptr 找函数(行为多态) 虚继承: → 用 vbptr 找数据(共享基类) 本质: → 用“间接层”解决复杂性

进阶思考(面试加分)

👉 一个对象里:

  • vptr 有几个?
  • vbptr 有几个?
  • 多继承下 this 如何调整?

这些就是 C++对象模型的高级区

http://www.cnnetsun.cn/news/1788393.html

相关文章:

  • ofa_image-caption实操案例:为AI绘画工作流增加反向caption生成校验环节
  • Cloudflare推出EmDash内容管理系统挑战WordPress主导地位
  • 2025届学术党必备的降AI率神器推荐
  • 2025届最火的降重复率平台实测分析
  • 世界模型笔记
  • Product Hunt 每日热榜 | 2026-04-09
  • 速成正果经
  • 基于STM32的智能垃圾桶检测系统设计与实现
  • Cursor AI Pro 完全破解指南:终极免费使用方案
  • 颠覆级游戏串流解决方案:Sunshine全场景应用指南
  • 硅谷“甄嬛传”第二季!Ilya 与 Amodei 把 Sam Altman 再次推上审判席
  • 压力调节:Deadline前的心理调适——软件测试从业者的专业应对指南
  • 清明假期做了两天私活,5w到手。。
  • 如何高效获取阿里云盘Refresh Token:开源工具实战指南
  • EF Core 10向量搜索不是“加个NuGet包”那么简单:一位资深架构师用12小时重构遗留系统的真实复盘
  • ESXi 自动加入 vCenter:Kickstart 脚本高效部署指南
  • Qwen2-VL-2B-Instruct效果对比:与传统卷积神经网络图像分类的差异
  • 10分钟掌握APK-Installer:Windows上安装安卓应用的终极方案
  • HH-Lol-Prophet:基于数据智能分析的英雄联盟对局先知系统
  • VR-Reversal:终极免费VR视频转换工具,让3D沉浸体验在普通屏幕上重生
  • 如何用GPT-4o和知识图谱提升遥感图像分类准确率?实战教程分享
  • 从门电路到CPU核心:算术逻辑单元(ALU)的设计演进与实战解析
  • 【OpenClaw】通过 Nanobot 源码学习架构---()总体堵
  • Linux字符设备驱动开发:alloc_chrdev_region自动分配设备号的5个实用技巧
  • 库存优化如何降本增效?一文说清库存优化三大法
  • 突破原神帧率限制:genshin-fps-unlock工具的流畅游戏体验实现指南
  • 颠覆式OpenCore自动化配置:5分钟完成黑苹果EFI构建的终极解决方案
  • AI编程时代,人类程序员还剩下什么?不
  • 如何用开源工具实现信息隐身?揭秘隐写术的技术与实践
  • 总分不清ISTA 3E和ISTA 3B?一篇教你怎么选ISTA3B/ISTA3E