1

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!

Suvarna Pattayil
  • 5,136
  • 5
  • 32
  • 59
Alon Shmiel
  • 6,753
  • 23
  • 90
  • 138
  • 6
    Can I ask **why** you don't want it? This could be what **virtual inheritance** is for. – Adriano Repetti May 08 '13 at 11:08
  • 1
    Possible answer can be found [here](http://stackoverflow.com/questions/137282/how-can-avoid-the-diamond-of-death-in-c-if-i-use-multiple-inheritance). – Suvarna Pattayil May 08 '13 at 11:12
  • 2
    Oh dear lord. Really? All those abbreviations.... – Lightness Races in Orbit May 08 '13 at 11:17
  • 1
    If you tell us why you need it, maybe we show a solution to solve the problem indirectly, I think there is not a real application which needs this issue. – masoud May 08 '13 at 11:17
  • @MM. there are some neat applications of virtual inheritance and most derived subtleties and all that, e.g. to emulate named template parameters (there's a nice section on that in Vandevoorde & Josuttis). But you are absolutely right: mortal user code should stay away from such huge class hierarchies. – TemplateRex May 08 '13 at 11:19

1 Answers1

2

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.

utnapistim
  • 26,809
  • 3
  • 46
  • 82