Pregunta

I have a class A.

classes B and C are interfaces that derives from class A.

      A
    /   \
   B     C

now I have to implement the classes D and E for both B and C.

and then there are some classes: FDB, GDC, HEC, IEB, JDB, KDC, LEB, MEC (while DB and DC in the end of the name of these classes means that the class uses D and B for the ending of DB, D and C for DC, E and B for EB, etc..

so:

class A..

class `B`: public virtual `A`..
class `C`: public virtual `A`..

class `D`: public B, public `C`..
class `E`: public B, public `C`..

class `FDB`: public `D`..
class `GDC`: public `D`..
class `HEC`: public `E`..
class `IEB`: public `E`..
class `JDB`: public `D`..
class `KDC`: public `D`..
class `LEB`: public `E`..
class `MEC`: public `E`..

but then I have a diamond inheritance and I don't want it.

can someone suggest another design please?

any help appreciated!

¿Fue útil?

Solución

What is the reason you want/need to avoid multiple inheritance?

Either way, if you cannot (do not want to) use inheritance in some of these cases, use encapsulation:

class A..

class `B`: public virtual `A`..
class `C`: public virtual `A`..

class `D`: public B {
private:
    C c_instance_;
};
class `E`: public B {
    C c_instance_;
};

... 

To avoid code duplication, you can create a C (or D) holder and inherit it through protected inheritance and CRTP. This way a separate base class holds the C base functionality but the classes that inherit from it do not have a common base class:

class A..

class B: public A..
class C: public A..

template<class Specialized, class DependedOn>
class DependsOn {
protected:
    DependedOn& get() { return implementation_; }
private:
    DependedOn implementation_;
};

class D: public B, protected DependsOn<D, C> .. // inheritance with CRTP
class E: public B, protected DependsOn<E, C> .. // inheritance with CRTP

class FDB: public D, protected DependsOn<FDB, B> .. 

D, E, FDB and so on, will use the get() method internally (or more specifically, DependsOn<D, C>::get(), DependsOn<E, C>::get() and so on) to implement the public interface.

Since DependsOn<D, C> is different from DependsOn<E, C>, you only have a common interface implemented by the whole hierarchy.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top