我有如下情况:
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
派生自 B
和 C
。但是有一些已知的问题(例如,
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/