资讯动态

多态的理解,虚函数表的理解

发布时间:2026/8/20 0:01:47 来源:尧图企业网站定制
#include iostream using namespace std; class Plane { public: virtual void fly() { cout "灰机正在飞行" endl; } virtual void showInfo() { cout "灰机正在展示" endl; } }; class AirBus : public Plane { public: void fly() override { cout "空中客车在飞行" endl; } void showInfo() override { cout "空中客车正在展示" endl; } }; class J20 : public Plane { public: void fly() override { cout "J20正在隐形战斗寻航" endl; } }; int main() { Plane* plane = new AirBus; return 0; }分析代码逐段 + 内存布局 + 调用逻辑完整解析1. 内存情况(64 位 MSVC)new AirBus在堆上创建一个AirBus 对象单继承,只有一份__vfptr(虚函数表指针,占 8 字节)对象没有任何成员变量,所以堆上对象总大小:8字节堆内存(AirBus 对象)堆地址 ┌────────────────────┐ │ __vfptr │───→ AirBus 的虚函数表 vftable └────────────────────┘AirBus 虚函数表 vftable表格下标存放函数地址[0]AirBus::fly[1]AirBus::showInfo虚函数本身代码放在代码段,不在堆对象里;对象只存虚表指针。栈上变量Plane* plane:这是指针变量,栈上占8 字节保存堆上 AirBus 对象的起始地址。注意:指针的类型是Plane*,但它存的是实打实 AirBus 对象的堆地址。 VS 调试窗口看到:plane Plane* {AirBus},代表静态类型 Plane*,实际动态类型 AirBus。2. 补充两条调用看效果plane-fly(); plane-showInfo();执行流程(动态绑定、多态)拿plane中保存的堆对象地址,找到对象头部__vfptr__vfptr指向 AirBus 虚函数表fly()取虚表[0],调用AirBus::fly→ 输出:空中客车在飞行showInfo()取虚表[1],调用AirBus::showInfo→ 输出:空中客车正在展示3. 对比 J20Plane* p2 = new J20; p2-fly(); // J20重写fly,虚表[0] = J20::fly,输出J20正在隐形战斗寻航 p2-showInfo(); // J20没有重写showInfo,虚表[1] = Plane::showInfo,输出灰机正在展示J20 虚函数表表格下标函数地址[0]J20::fly[1]Plane::showInfo4. 重点回顾单继承关键点单继承,无论多少个 virtual,对象永远只有 1 个__vfptr;子类 override 重写虚函数,不去修改对象里的__vfptr 本身,而是修改虚表里面存储的函数地址;override只是编译期检查:确保父类有这个虚函数,不会改变内存布局;VS 调试看到两个__vfptr,是调试器 UI 重复展开,堆内存物理上就一份;只有多重继承、两个互不相关父类各自带虚函数,对象内存才出现多份独立__vfptr。5. 内存大小汇总(64 位 MSVC)表格类型sizeof说明Plane8仅__vfptrAirBus8继承,无新增成员变量,一份__vfptrJ208继承,无新增成员变量,一份__vfptrPlane*8指针本身大小,和指向什么对象无关6. 内存泄漏提醒代码中new AirBus堆分配,没有写delete plane;,程序退出前没有释放堆内存,造成内存泄漏。cppint main() { Plane* plane = new AirBus; delete plane; //释放堆对象 return 0; }⚠这里有个重要知识点:基类析构函数如果不是 virtual,delete 基类指针不会正确调用子类析构!给你演示坑:cppclass Plane { public: virtual void fly(){} //~Plane(){} //普通析构,不是virtual,delete plane;只会调用Plane析构,不会调用AirBus析构! virtual ~Plane(){} //✅虚析构,多态delete才完整释放子类资源 };

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价