gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-28 00:15:12 25 4
gpt4 key购买 nike

我正在阅读 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com