我有如下情况:

class A {
    virtual void f() { /*some default impl here*/}
    virtual void g() { /*some default impl here*/}
};

class B : public A {
    virtual void f() { /* do some specific stuff and call parent's f()*/}
    virtual void g() { /* do some specific stuff and call parent's g()*/}
};

class C : public A {
    virtual void f() { /* do some specific stuff and call parent's f()*/}
    virtual void g() { /* do some specific stuff and call parent's g()*/}
};

class mixed /* I don't know how to derive*/ {
    virtual void f() { /* call B::f()*/}
    virtual void g() { /* call C::g()*/}
};

我在这里考虑多重继承。即,使 mixed 派生自 BC
但是有一些已知的问题(例如,
Diamond problem)。

另一种解决方案可能是组合。

但什么是正确的解决方案,请指教:)

提前致谢!

最佳答案



第一:除非您明确创建,否则没有菱形图案。

 class mixed: public B, public C

这将使混合继承 B 和 C。每个都有自己的显式 A(无菱形)。

由于 B 和 C 都有从 A 派生的虚拟成员,因此应该调用哪个成员变得不明确,但是您已经通过在 mixed 中明确定义所有虚拟成员来解决这个问题(因此问题解决了)。
  void mixed::f() { B::f();} // works fine.

现在,即使您明确创建了钻石。

注意:菱形图案不会正常出现。菱形模式是您必须 明确做出的设计决策 并使用它来解决某些类型的问题(通过使用虚拟继承)。
class B: public virtual A ...
class C: public virtual A ...
class mixed: public B, public C ...

你仍然没有问题。因为 mixed::f() 只使用 B 分支(然后是 A)。而 mixed::g() 只使用 C 分支(然后是 A)。

即使 A 有它自己的状态(虽然这可能是一个坏主意,通常最好使用接口(interface)作为虚拟基类),那么我们也没有问题,因为 mixed::f()mixed::g() 只在一个 child 中调用一个函数(问题开始如果他们调用双方并且 A 的状态被两个调用改变,就会发生这种情况。



那也行。
 class mixed: public A
 {
     B    b;
     C    c;
     public:
         virtual void f() override {b.f();}
         virtual void g() override {c.g();}
     ....
 };



没有正确的解决方案。这在很大程度上取决于你没有提到的细节(比如 A 的细节是什么)。

但是 的一般建议是更喜欢组合而不是继承,但这只是一般建议,细节总是会归结为要解决的实际问题。

关于c++ - 是否需要多重继承?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31409061/

10-09 15:10