这直接取自您所描述的类的对象布局转储。我希望它能回答你的问题。从更多的研究中,我发现vtordisp
对于 class Base
。是从使用虚基声明的类的构造函数或析构函数调用虚函数时使用的偏移量。显然是告诉他们你的虚函数表在哪里。
来自MSFT 的 Jonathan Caves, 5 年前:
它很少使用——但我们必须将它添加到从虚拟基类继承的类中并覆盖虚拟函数,以防用户在构造函数或析构函数中调用虚拟函数。
1>
注意:对所有行的序言感到抱歉。怪微软,它是他们的工具。
1> class RootBase size(8):
1> +---
1> 0 | {vfptr}
1> 4 | ai
1> +---
1>
1> RootBase::$vftable@:
1> | &RootBase_meta
1> | 0
1> 0 | &RootBase::fas
1>
1> RootBase::fas this adjustor: 0
1>
1>
1> class Base size(24):
1> +---
1> 0 | {vfptr}
1> 4 | {vbptr}
1> 8 | bai
1> +---
1> 12 | (vtordisp for vbase RootBase)
1> +--- (virtual base RootBase)
1> 16 | {vfptr}
1> 20 | ai
1> +---
1>
1> Base::$vftable@Base@:
1> | &Base_meta
1> | 0
1> 0 | &Base::fa
1>
1> Base::$vbtable@:
1> 0 | -4
1> 1 | 12 (Based(Base+4)RootBase)
1>
1> Base::$vftable@RootBase@:
1> | -16
1> 0 | &(vtordisp) Base::fas
1>
1> Base::fas this adjustor: 16
1> Base::fa this adjustor: 0
1>
1> vbi class offset o.vbptr o.vbte fVtorDisp
1> RootBase 16 4 4 1
采用完全相同的代码,但制作RootBase
常规基类(即 not ,virtual public RootBase
just public RootBase
)对对象布局有显着影响:
1> class RootBase size(8):
1> +---
1> 0 | {vfptr}
1> 4 | ai
1> +---
1>
1> RootBase::$vftable@:
1> | &RootBase_meta
1> | 0
1> 0 | &RootBase::fas
1>
1> RootBase::fas this adjustor: 0
1>
1>
1> class Base size(12):
1> +---
1> | +--- (base class RootBase)
1> 0 | | {vfptr}
1> 4 | | ai
1> | +---
1> 8 | bai
1> +---
1>
1> Base::$vftable@:
1> | &Base_meta
1> | 0
1> 0 | &Base::fas
1> 1 | &Base::fa
1>
1> Base::fas this adjustor: 0
1> Base::fa this adjustor: 0
请注意,随着虚拟基础的消失,不再存储“我是谁”偏移量,这似乎可以很好地清理对象格式。