简体   繁体   中英

Avoiding redundant code in a hierarchy of classes

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?

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++?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM