0

I have a specific case (in C++) where I would like to avoid having the same code repeated all over a set of classes that derive from another set of classes where I can not paste this code into. And solving this issue somehow ends up with the diamond inheritance problem. The following example will explain the situation:

template <class T>
class A{
    ...
    virtual List<T>* create_list() = 0;   //Factory method
};

template <class T> 
class B: public A{
    ... // Does NOT implement create_list, as 
    //List is an abstract class and is not implemented
    //at this level of abstraction
};

Now, we have a set of classes which derive from either of the above abstract classes.

class C: public A{};
class D: public B{};
class E: public B{};
... and so on

And we have an implementation for List in the form of VectorList

All of them have to implement create_list by returning a VectorList. The implementation is the same for all of them:

VectorList* create_list(){
   return new VectorList;
}

The only way I can think of, which will not need me to repeat the above line of code in all of C,D and the other such classes, is to create a class X that implements A and make all these perform multiple inheritance. That is,

class X: public A{
    VectorList* create_list(){
      return new VectorList;
    }
};
class C: public A, public X;
class D: public B, public X;

However, this creates the diamond inheritance problem which would mean the I have to use virtual inheritance. But I understand that it is not a good design.

Is there any other alternative?

AntonH
  • 6,359
  • 2
  • 30
  • 40
Enigman
  • 640
  • 3
  • 9
  • 21
  • 1
    You might want to take a look at the [`CRTP`](http://stackoverflow.com/questions/4173254/what-is-the-curiously-recurring-template-pattern-crtp). That should do what you need, if just creating a common intermediate base class is not enough. – Deduplicator May 03 '14 at 21:28
  • If all the classes implement the same, why do you need a virtual function at all? Or at best only override once when needed. You don't *have* to make all virtual functions pure in an abstract base. – Kerrek SB May 03 '14 at 21:29
  • I don't really understand the link. I just went through the pattern you referred to. Could you elaborate that in this context, please? – Enigman May 03 '14 at 21:30
  • @KerrekSB: All of them implement the same thing, yes. But I dont want it to be implemented at the level of abstraction of A or B. That is, I want the `create_list` to be undefined at that level. Whoever implements the classes A and B, has the liberty to implement it however they want it. It so happens that in my choice of implementation, that is, in C and D, I decided to implement it all of them the same way. – Enigman May 03 '14 at 21:32
  • The CRTP is a way to write code which shall be inserted into multiple classes, and allows parameterising it with the target class and additional info as needed. – Deduplicator May 03 '14 at 21:32
  • @Deduplicator: it'll be nice if you could add an answer elaborating on how it can be used here. – Enigman May 03 '14 at 22:21
  • 1
    I can't tell from the level of detail here but you may have an issue with using inheritance where composition would be better. – Mike Stockdale May 04 '14 at 00:27

1 Answers1

0

Use interfaces and composition:

Create an interface for class A (lets call it IA). Create a default implementation for class A (lets call it implA)

class implA: public IA

Create an interface for class B (lets call it IB)

class IB: public IA

Create a default implementation for class B (lets call it implB)

class implB: public implA, public IB

Implement your create_list method in implA. C, D and E should be:

class C: public implA
class D: public implB
class E: public implB

For more information on Interfaces in c++ see: How do you declare an interface in C++?

Community
  • 1
  • 1
Kicsi
  • 1,173
  • 10
  • 22