C++ – 虚拟继承的实现

1. 实现技术的挑战:
要找到一个足够有效的方法,将istream和ostream各自维护一个ios subobject,折叠成为一个由iostream维护的单一ios subobject,并且还可以保存base class和derived class的指针之间的多态指定操作。

2. 一种实现方法:
class如果内含一个或多个virtual base class subobject,像istream那样,将被分割为两部分:一个不变局部和一个共享局部。

不变局部中的数据,不管后继如何衍化,总是拥有固定的offset,所以这部分数据可以被直接存取。

至于共享局部,所表现的就是virtual base class subobject。这一部分数据,其位置会因为每次的派生操作而有变化,所以它们只可以被间接存取。

各家编译器实现技术之间的差异就在于间接存取的方法不同。主要有三种主流策略。

3. 布局策略之一:
先安排好derived class的不变部分,然后再建立其共享部分。在每一个derived class object中安插一些指针,每个指针指向一个virtual base class(这意味着,如果有多个虚基类,则需要多个指针分别依次指向)。要存取继承得来的virtual base class members,可以使用相关指针间接完成。

4. 布局策略一的缺点:
(1)每一个对象必须针对其每一个virtual base class背负一个额外的指针。
(2)由于虚拟继承串链的加长,导致间接存取层次的增加。

5. MetaWare编译器:
针对问题(2),通过拷贝操作获取所有嵌套的虚基类指针(nested virtual base class pointer),放到derived class object之中,这样就解决了“固定存取时间”的问题,不会出现间接存取层数增加的情况,但是付出了空间上的代价。

6. Microsoft编译器:
针对问题(1),引入虚基类表(virtual base class table),每一个class object如果有一个或多个虚基类(virtual base class),就会由编译器安插一个指针,指向虚基类表(virtual base class table),至于真正的virtual base class指针,当然是放在该表格中。

7. Bjarne解决方法:
针对问题(1),在virtual function table中放置virtual base class 的offset,而不是地址。

8. Sun编译器:
针对问题(1),将virtual base class offset和virtual function entries混杂在一起,virtual function table可经由正值或负值来索引,如果是正值,索引到virtual functions;如果是负值,索引到virtual base class offsets。

9. 优化:
经由一个非多态的class object来存取一个继承而来(即:派生类对象中的虚基类部分)的virtual base class的member,像这样:
Point3d origin;
origin._x; // _x为虚基类Point2d的成员
可以被优化为一个直接存取操作,就好像一个经由对象调用的virtual function调用操作,可以再编译时期被决议完成一样。在这次存取以及下次存取之间,对象的类型不会改变(因为前提是非多态),所以“virtual base class subobject的位置会变化”的问题在这种情况下就不再存在了。

10. 常用形式:
一般而言,virtual base class最有效的一种运用形式就是:一个抽象的virtual base class,没有任何data members。

原文链接: https://www.cnblogs.com/xushjie/archive/2012/09/26/2704810.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C++ - 虚拟继承的实现

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/63801

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 上午11:09
下一篇 2023年2月9日 上午11:09

相关推荐