我读了这篇文章: https ://shaharmike.com/cpp/vtable-part2/
而且我不明白为什么在 vtable 中(在文章末尾)我们有这个指针:
0x400918 0x400820 非虚拟 thunk 到 Child::FatherFoo()
但不是直接指向方法 Child::FatherFoo() 的指针?
我假设 Child 的 vtable 与 Father 的 vtable 完全分开。
我读了这篇文章: https ://shaharmike.com/cpp/vtable-part2/
而且我不明白为什么在 vtable 中(在文章末尾)我们有这个指针:
0x400918 0x400820 非虚拟 thunk 到 Child::FatherFoo()
但不是直接指向方法 Child::FatherFoo() 的指针?
我假设 Child 的 vtable 与 Father 的 vtable 完全分开。
就像 C 结构中除了一个之外的所有成员不能与包含对象具有相同的地址一样,除了一个非空基类子对象之外的所有成员都不能与完整对象具有相同的地址;根据定义,多态基类(具有虚函数的基类)不是空的。
与派生对象具有相同地址的多态基子对象称为主基。派生对象与主要基础共享 vtable 布局的基础和 vptr:隐式this
参数不会更改。
注意:primary base 的概念是 C++ 实现域概念(如 vtable、vptr...),而不是 C++ 语言概念(如基类、虚函数...)。所以,很明显,它没有在 C++ 标准中描述。
当通过虚调用机制对未知动态类型的对象动态调用虚函数时,this
必须将隐式参数调整为正确的值,即非主基的不同值。执行此操作的中介称为 thunk。在这种情况下,thunk 可以跳转到正确的函数而不是函数调用:额外的工作发生在函数入口处,而函数出口处不需要任何东西。
当使用协变返回类型并且协变返回的派生到基础关系不是派生到主要基础关系时,会发生另一种类型的调整。显然,这种 thunk 不会进行跳转,而是进行函数调用,因为协方差的调整发生在函数退出时。