我正在读这篇文章“虚拟方法表"
上面文章中的例子:
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(),如果我们想访问 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
它已经具有该连续内存布局的起始地址的一定偏移量。例如我们想要访问b1
在 D::f2() 内部,我想在运行时,它会执行类似以下操作:*(this+4)
(this
指向与 b2) 相同的地址,这将指向b2
in B
????