【问题标题】:c++ vtable in multiple inheritance, pointer to thunk method多继承中的c ++ vtable,指向thunk方法的指针
【发布时间】:2018-02-26 21:15:04
【问题描述】:

我读了这篇文章: https://shaharmike.com/cpp/vtable-part2/

我不明白为什么在 vtable 中(在文章末尾)我们有这个指针:

0x400918 0x400820 非虚拟 thunk 到 Child::FatherFoo()

但不是直接指向方法 Child::FatherFoo() 的指针?

我假设 Child 的 vtable 与 Father 的 vtable 完全分开。

【问题讨论】:

  • 这篇文章很好地解释了这一点我认为Here’s the solution: the compiler creates a ‘thunk’ method that corrects this and then calls the ‘real’ method. The address of the thunk method will sit under Child’s Father vtable, while the ‘real’ method will be under Child’s vtable.这也起到了这句话In other words, for a given Child c;: (void*)&c != (void*)static_cast<Father*>(&c)的作用,它告诉你为什么需要调整this指针
  • 当通过Father*访问FatherFool()时,“this”指针指向示例中的第二个vtable。 thunk 主要用于将“this”指针调整到对象的最顶部,这是一个关键步骤,因为映像 Child::FatherFoo() 可以访问 Mother 或 Child 中的数据成员。

标签: c++ multiple-inheritance vtable virtual-functions vptr


【解决方案1】:

就像 C 结构中除了一个之外的所有成员不能与包含对象具有相同的地址,除了一个非空基类子对象之外的所有成员都不能与完整对象具有相同的地址;根据定义,多态基类(具有虚函数的基类)不为空。

与派生对象具有相同地址的多态基础子对象称为主基础。派生对象共享 vtable 布局的基础和与主要基础的 vptr:隐式 this 参数不会更改。

注意:primary base 的概念是一个 C++ 实现域概念(如 vtable、vptr...),而不是 C++ 语言概念(如基类、虚函数...)。所以,很明显,它没有在 C++ 标准中描述。

当通过虚调用机制在未知动态类型的对象上动态调用虚函数时,必须将this隐式参数调整为正确的值,这是非主基的不同值.执行此操作的中介称为 thunk。在这种情况下,thunk 可以跳转到正确的函数而不是函数调用:额外的工作发生在函数入口处,而函数出口处不需要任何工作。

当使用协变返回类型并且协变返回的派生到基础关系不是派生到主要基础关系时,会发生另一种类型的调整。显然,这种 thunk 不会进行跳转,而是进行函数调用,因为协方差的调整发生在函数退出时。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-30
    • 2016-09-02
    • 2016-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-28
    相关资源
    最近更新 更多