模糊使用C ++虚拟继承

时间:2013-08-10 18:21:38

标签: c++ virtual-inheritance

C ++中的虚拟继承是防止钻石问题的有效方法。但是,我似乎无法在每个案例中使其正常工作。

这将很难解释,但我希望我会管理。让我们来解决问题:

A继承B. A是名为C的类集的基类,另一个是名为D的类。

问题在于C类的集合具有围绕B的共同特征。

我想做什么,但是不可能,是一个真正继承B的E类,它由C继承。问题是:

在这种情况下,A实际上并不继承B.所以它不起作用。

如果A实际上是继承B,那么我需要在每个D类中使用B的构造函数。

结论:在每个案例中都存在重复的代码。如果没有任何重复的代码,我怎么能摆脱这个问题?

2 个答案:

答案 0 :(得分:1)

好的,所以你说你有:

                             B
                             +
                             |
                             v
                             A
                             +
                        +----+----+
                        v         v
                        C         D

所有这些都是非虚拟继承,然后您拥有 virtualy 继承E的类B,而C也继承了它,因此完整的图表将是:

                +-----------+B
                |            +
                |            |
                v            v
                E            A
                +            +
                +---+---+----+----+
                    v             v
                    C             D                                  

B继承了E virtualy 的例外情况。

解决方案很简单,您应该A也虚拟继承B,但我从您的问题中收集到您无法修改A。您的下一个选项是让C继承AE并拥有另一个的实例,这称为delegation. 另一种方法是,您可以提供一个通用接口并允许多态,您可能希望创建一个接口(纯虚拟类),该接口具有E C使用的所有功能,然后使CE派生出该界面。 E将从接口实现虚函数,C将实现它作为E实现的函数调用。或者(不推荐)你可以忍受死亡的钻石,如果它对你没有问题,但是确定这是棘手的,我不建议这是一个可怕的想法。

答案 1 :(得分:1)

B拆分为接口部分IB(抽象基类,无数据成员)和实现部分Bimpl。 Multiply-inherit only IB。由于IB没有数据成员,因此不需要非默认构造函数,因此您无需在任何地方重复它。

对于因此更改而变为抽象的层次结构中的每个类C,请创建继承自CimplC的{​​{1}}。永远不要继承BimplCimpl的非默认构造函数(以前为Bimpl)仅在B中调用。