gpt4 book ai didi

c++ - 多重继承的虚方法表

转载 作者:可可西里 更新时间:2023-11-01 18:36:48 25 4
gpt4 key购买 nike

我正在阅读这篇文章“Virtual method table

上面文章中的例子:

class B1 {
public:
void f0() {}
virtual void f1() {}
int int_in_b1;
};

class B2 {
public:
virtual void f2() {}
int int_in_b2;
};

class D : public B1, public B2 {
public:
void d() {}
void f2() {} // override B2::f2()
int int_in_d;
};

B2 *b2 = new B2();
D *d = new D();

作者在文章中介绍对象d的内存布局是这样的:

          d:
D* d--> +0: pointer to virtual method table of D (for B1)
+4: value of int_in_b1
B2* b2--> +8: pointer to virtual method table of D (for B2)
+12: value of int_in_b2
+16: value of int_in_d

Total size: 20 Bytes.

virtual method table of D (for B1):
+0: B1::f1() // B1::f1() is not overridden

virtual method table of D (for B2):
+0: D::f2() // B2::f2() is overridden by D::f2()

问题是关于d->f2()的。对 d->f2() 的调用将 B2 指针作为 this 指针传递,因此我们必须执行如下操作:

(*(*(d[+8]/*pointer to virtual method table of D (for B2)*/)[0]))(d+8) /* Call d->f2() */

为什么我们应该传递一个 B2 指针作为 this 指针而不是原始的 D 指针???我们实际上是在调用 D::f2()。根据我的理解,我们应该将 D 指针作为 this 传递给 D::f2() 函数。

___更新____

如果将 B2 指针作为 this 传递给 D::f2(),如果我们想访问 B1 类的成员怎么办在 D::f2() 中?我相信 B2 指针 (this) 显示如下:

          d:
D* d--> +0: pointer to virtual method table of D (for B1)
+4: value of int_in_b1
B2* b2--> +8: pointer to virtual method table of D (for B2)
+12: value of int_in_b2
+16: value of int_in_d

它已经有了这个连续内存布局的起始地址的一定偏移量。例如,我们想在 D::f2() 中访问 b1,我猜在运行时,它会做类似这样的事情:*(this+4) (this 指向与 b2 相同的地址)这将指向 B 中的 b2 ????

最佳答案

我们不能传递 D指向覆盖 B2::f2() 的虚函数的指针,因为同一个虚函数的所有重写都必须接受相同的内存布局。

B2::f2()函数期望 B2传递给它的对象的内存布局为 this指针,即

b2:
+0: pointer to virtual method table of B2
+4: value of int_in_b2

覆盖函数 D::f2()也必须期望相同的布局。否则,这些功能将无法互换。

要了解为什么互换性很重要,请考虑以下场景:

class B2 {
public:
void test() { f2(); }
virtual void f2() {}
int int_in_b2;
};
...
B2 b2;
b2.test(); // Scenario 1
D d;
d.test(); // Scenario 2

B2::test()需要调用f2()在这两种情况下。它没有额外的信息来告诉它如何this进行这些调用时必须调整指针*。这就是编译器传递固定指针的原因,所以 test() f2的来电可以与 D::f2() 一起使用和 B2::f2() .

* 其他实现可能会很好地传递此信息;然而,本文中讨论的多重继承实现并没有这样做。

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

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