-2

C++ 中的虚拟继承是防止菱形问题的有用方法。但是,我似乎无法使其在每种情况下都能正常工作。

这将很难解释,但我希望我能做到。让我们提出问题:

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

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

我想做但不可能的是一个类 E,它实际上继承了 B,并且由 C 继承。问题是:

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

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

结论:在每种情况下都有重复的代码。在没有任何重复代码的情况下,我怎样才能摆脱这个问题?

4

2 回答 2

1

好的,所以你说你有:

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

所有这些都是非虚拟继承,然后你有虚拟继承并继承它的类所以一个E完整的图表将是:BC

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

除了虚拟继承B的例外。E

解决方案很简单,您应该A也可以虚拟继承B,但是我从您的问题中收集到您无法修改A。您的下一个选择是C继承AE拥有另一个实例,这称为委托。 另一种方法是,您可以提供一个通用接口并允许多态性,您可能希望创建一个具有EC使用的所有功能的接口(纯虚拟类),然后创建CE派生该接口。E将从接口实现虚函数,C 将其实现为函数调用E的实施。或者(不推荐)如果它对您没有问题,您可以与死亡钻石一起生活,但是确定这很棘手,我不推荐这是一个糟糕的主意。

于 2013-08-10T18:42:17.640 回答
1

分为B接口部分IB(抽象基类,无数据成员)和实现部分Bimpl 乘法继承IB。由于IB没有数据成员,因此不需要非默认构造函数,因此您不必到处重复它。

C对于层次结构中由于这种变化而变得抽象的每个类,创建Cimpl继承自C和的类Bimpl。永远不要继承自Cimpl. 的非默认构造函数Bimpl,以前是 的B,仅在 中调用C

于 2013-08-10T18:50:25.767 回答