多重继承的虚拟方法表

菲霍普

我正在阅读本文“虚方法表

以上文章中的示例:

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指向thisD :: f2()函数指针

___更新____

如果传递一个B2指向thisD :: 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

它已经对该连续内存布局的起始地址具有一定的偏移量。例如,我们要访问b1内部d :: F2(),我想在运行时,它会做这样的事情:*(this+4)this指向同一地址B2),这将分b2B????

谢尔盖·卡里尼琴科(Sergey Kalinichenko)

我们不能将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()

*其他实现可能很好地传递此信息;但是,本文中讨论的多重继承实现无法做到这一点。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

多重继承/虚拟功能

来自分类Dev

C ++多重和虚拟继承

来自分类Dev

C ++纯虚拟多重继承?

来自分类Dev

虚拟多重继承和转换

来自分类Dev

非虚拟多重继承的示例

来自分类Dev

C ++多重和虚拟继承

来自分类Dev

关于多重继承和虚拟继承

来自分类Dev

没有虚拟继承的多重继承

来自分类Dev

多重继承的替代方法

来自分类Dev

是否可以通过虚拟支持多重继承?

来自分类Dev

SWIG JAVA如何使用%interface和纯虚拟方法包装C ++多重继承

来自分类Dev

C ++多重继承,虚拟方法覆盖问题和协变返回类型

来自分类Dev

虚拟方法继承类

来自分类Dev

虚拟方法继承类

来自分类Dev

jOOQ抱怨排除表的多重继承

来自分类Dev

多重虚拟继承是否涉及后期绑定,例如虚拟函数的继承?

来自分类Dev

多重虚拟继承是否涉及后期绑定,例如虚拟函数的继承?

来自分类Dev

具有虚拟功能的C ++中的多重继承

来自分类Dev

多重继承导致虚假的模糊虚拟函数重载

来自分类Dev

Python和多重继承中的方法顺序

来自分类Dev

Python调用父方法多重继承

来自分类Dev

哪个是php中多重继承的最佳方法?

来自分类Dev

python类多重继承中的方法重写

来自分类Dev

Python调用父方法多重继承

来自分类Dev

在多重继承中调用超类方法

来自分类Dev

多重继承

来自分类Dev

继承的类重写虚拟方法依赖项

来自分类Dev

如何继承泛型虚拟方法?

来自分类Dev

cpp继承虚拟方法解析顺序