You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

含纯虚基类的派生类共用体运行时行为解析

底层运行机制解析

首先明确几个核心底层逻辑:

  • Union的内存特性:Union的所有成员共享同一块连续内存空间,theDers.D1和theDers.D2的起始地址完全相同,整个union对象的内存大小等于其最大成员的大小(这里两个派生类大小一致,因为都仅继承了带纯虚函数的Base,无额外成员)。
  • C++虚函数的实现原理:带有虚函数的类,其对象实例的内存布局最开头会包含一个虚表指针(vptr),该指针指向对应类的虚函数表(vtable)——虚表中存储了类的虚函数地址。当类的构造函数执行时,会将对象的vptr设置为当前类的虚表地址,这是保证虚函数多态调用的核心。

回到你的代码运行流程:

  1. 全局union对象theDers通过构造函数初始化了D1,也就是执行了Der1的构造函数。此时,theDers对应的内存块中,vptr被设置为Der1类的虚表地址。
  2. 第一次调用b->Func()时,通过b指向的对象中的vptr找到Der1的虚表,调用Der1::Func(),输出"Der1"。
  3. 当执行b = &theDers.D2时,只是改变了指针b的指向,但**Der2的构造函数从未被调用过**——union不会自动构造未被初始化的成员,这块共享内存的vptr仍然是之前Der1构造时设置的那个,指向Der1的虚表。
  4. 第二次调用b->Func()时,依然是通过内存中未被更新的vptr找到Der1的虚表,因此还是调用Der1::Func(),再次输出"Der1"。

本质上:你只是修改了指针的指向,但目标内存里的虚表指针根本没被更新成Der2的,因为Der2对象从未被正确构造过,虚函数调用的逻辑自然还是走Der1的实现。

内容的提问来源于stack exchange,提问作者Ashley Duncan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 03:31:22