多重或虚拟继承下类的内存布局和虚函数表?

18

我正在阅读《C++对象模型》一书,试图理解如何通过虚表实现多继承和虚继承。(我已经很好地理解了单一多态性)。

当需要在虚继承或转换期间定位方法时,我很难理解到底发生了什么,因为需要执行许多偏移量计算。

是否有人能够帮助理解多重虚拟表是如何在多继承或虚继承示例中使用的?如果我能理解布局和问题,我可能会更好地理解这个问题。


当你说多重继承时,是指连续的派生(c继承自b,b继承自a),还是真正的多重继承(c同时从a和b继承)? - Christophe
1
也许这个问题可以帮到你:https://dev59.com/i2gu5IYBdhLWcg3wEzHP - Olaf Dietsche
1个回答

17

C++的实现通常使用虚函数表(vtable)来实现虚函数。虚函数表是一个指向函数指针的表格。每个带有虚函数的类对象都有一个隐藏的指向包含该类所有虚函数地址的vtable指针。

调用虚函数时,代码会计算出vtable中函数指针的偏移量,并调用存储在那里的函数。

enter image description here

当派生类覆盖(base class的)虚函数时,该类的虚函数表仅指向被覆盖的函数而不是原始函数。

这篇优秀的文章详细解释了它是如何工作的,包括单一和多重继承。


2
这仅适用于单一继承。如果我们有 class B: virtual public A{ 呢? - Bogdan Mart
1
@BogdanMart 我尝试回答OP的主要问题。对于包括虚继承在内的MI的高级情况,我诚邀您阅读我提供链接的文章。它提供了所有必要的细节。 - Christophe
我来这里是为了寻找带有虚拟类继承的多重继承。我是漏掉了什么还是你只是在解释普通的虚拟函数? - NirIzr
@NirIzr 由于问题比较广泛,我在评论中提出了一个细化的问题,并准备好了另一个问题,以查看我的答案需要多具体。OP没有回答我的第一个问题,所以我解释了vtable和offsets如何计算(问题的第二部分),并引用了一篇文章,解释了在MI和VI的情况下如何找到正确的vtable。两者加起来涵盖了所有问题。如果您特别关注VI,则答案中链接的文章可能会有所帮助。 - Christophe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接