c++ - c++多重继承的理解

标签 c++ this multiple-inheritance virtual-functions vtable

我正在阅读 multiple inheritance for c++ 论文中的一个例子:(第377页)

class A {virtual void f();};
class B {virtual void f(); virtual void g();};
class C: A, B {void f();};
A* pa = new C;
B* pb = new C;
C* pc = new C;
pa->f();
pb->f();
pc->f();
pc->g()

(1) Bjarne 写道:在进入 C::f 时,this 指针必须指向 C 对象的开头(而不是 B 部分)。但是,在编译时通常不知道 pb 指向的 BC 的一部分,因此编译器无法减去常量 delta(B)。所以我们必须存储实际与 vtbl 一起存储的运行时的 delta(B)。所以 vtbl 条目现在看起来像:

struct vtbl_entry {
    void (*fct)();
    int  delta;
}

类 c 的对象将如下所示:

----------             vtbl: 
   vptr -------------->-----------------------
   A part                C::f   | 0 
----------             -----------------------   
   vptr -------------->----------------------- 
   B part                C::f   | -delta(B)
----------               B::g   | 0
   C part              -----------------------
----------

比亚恩写道:

pb->f() // call of C::f:
register vtbl_entry* vt = &pb->vtbl[index(f)];
(*vt->fct)((B*)((char*)pb+vt->delta)) //vt->delta is a negative number I guess

我在这里完全糊涂了。为什么 (B*)(*vt->fct)((B*)((char*)pb+vt->三角洲))????根据我的理解和 Bjarne 在第 377 页 5.1 部分第一句的介绍,我们应该在这里传递一个 C* 作为 this!!!!!!

接着上面的代码片段,Bjarne 继续写道: 请注意,对象指针可能必须调整为 po 在查找指向 vtbl 的成员之前,将其转换为正确的子对象。

哦,伙计!我完全不知道 Bjarne 想说什么?你能帮我解释一下吗?

最佳答案

一个C*,只是不是这样输入的。

坦率地说,这是一个非常糟糕的解释,而不是它是如何完成的。在 vtable 中存储函数指针会更好也更容易。

struct vtbl {
    void(*f)(B* b);
};
struct B {
   vtbl* vtable;
};
// Invoke function:
B* p = init();
p->vtable->f(p);
// Function pointer points to:
void f_thunk(B* b) {
    C* c = (char*)b - delta(B);
    C::f(c);
}

当编译器生成 thunk 时,它知道它们正在 thunk 到的派生对象,因此它们不需要将偏移量存储在 vtable 中。编译器可以简单地偏移 thunk 中的指针,然后用指针委托(delegate)给适当的方法。当然,这个 thunk 几乎只是生成的程序集,没有任何 C++ 表示,因此声明其中的指针具有任何特定的 C++ 类型是无效的。

关于c++ - c++多重继承的理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30768589/

相关文章:

java - 要求参数扩展特定类并实现特定接口(interface)

c++ - 使用模板时启用 visual studio c++ 语法错误警告

javascript - 在 vuejs 中,如何引用方法内完成的函数中的数据?

java - 如何创建多 war war 模块?

c++ - 多重继承使私有(private)成员可访问

Java这个参数

c++ - qSort 的问题

c++ - 程序终止时调用的析构函数

C++:全局变量的重新定义

javascript - 在 JavaScript 上使用 "this"编写函数时出现语法错误