Fih*_*hop 7 c++ pointers this multiple-inheritance this-pointer
我正在读这篇文章" 虚方法表 "
上面的文章中的示例:
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();
Run Code Online (Sandbox Code Playgroud)
在文章中,作者介绍了对象的内存布局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()
Run Code Online (Sandbox Code Playgroud)
问题是关于d->f2().调用d->f2()将B2指针作为this指针传递,因此我们必须执行以下操作:
(*(*(d[+8]/*pointer to virtual method table of D (for B2)*/)[0]))(d+8) /* Call d->f2() */
Run Code Online (Sandbox Code Playgroud)
我们为什么要传递B2指针作为this指针而不是原始D指针??? 我们实际上是在调用D :: f2().根据我的理解,我们应该传递一个关于D :: f2()函数的D指针this.
___update____
如果将B2指针传递this给D :: f2(),如果我们想要访问B1D :: 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
Run Code Online (Sandbox Code Playgroud)
它已经具有该连续存储器布局的起始地址的某个偏移量.例如,我们要访问b1内部d :: F2(),我想在运行时,它会做这样的事情:*(this+4)(this指向同一地址B2),这将分b2在B????
我们不能将D指针传递给虚函数重写B2::f2(),因为同一虚函数的所有重写都必须接受相同的内存布局。
由于B2::f2()函数期望将B2对象的内存布局作为其this指针传递给它,即
b2:
+0: pointer to virtual method table of B2
+4: value of int_in_b2
Run Code Online (Sandbox Code Playgroud)
重写函数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
Run Code Online (Sandbox Code Playgroud)
B2::test()在这两种情况下都需要进行调用f2()。它没有额外的信息来告诉它this在进行这些调用时如何调整指针*。这就是编译器传递固定指针的原因,因此test()的调用f2适用于D::f2()和B2::f2()。
*其他实现很可能会传递此信息;然而,本文中讨论的多重继承实现并没有做到这一点。
| 归档时间: |
|
| 查看次数: |
227 次 |
| 最近记录: |