开发者

How to easily substitute a Base class

I have the following hierarchy of classes

class classOne
{
    virtual void abstractMethod() = 0;
};

class classTwo : public classOne
{
};

class classThree : public classTwo
{
};  

All classOne, classTwo and classThree are abstract classes, and I have another class that is defining the pure virtual methods

class classNonAbstract : public classThree
{
    void abstractMethod();

    // Couple of new methods
    void doIt();
    void doItToo();
};

And right 开发者_运维知识库now I need it differently...I need it like

class classNonAbstractOne : public classOne
{
    void abstractMethod();

    // Couple of new methods
    void doIt();
    void doItToo();
};

class classNonAbstractTwo : public classTwo
{
    void abstractMethod();

    // Couple of new methods
    void doIt();
    void doItToo();
};

and

class classNonAbstractThree : public classThree
{
    void abstractMethod();

    // Couple of new methods
    void doIt();
    void doItToo();
};

But all the nonAbstract classes have the same new methods, with the same code...and I would like to avoid copying all the methods and it's code to every nonAbstract class. How could I accomplish that?

Hopefully it's understandable...


template<class Base>
struct Concrete : Base {
  void abstractMethod();

  void doIt() {
    // example of accessing inherited members:
    int n = Base::data_member; // or this->data_member
    n = Base::method(); // non-virtual dispatch
    n = this->method(); // virtual dispatch

    // since Base is a template parameter, 'data_member' and 'method' are
    // dependent names and using them unqualified will not properly find
    // them
  }
  void doItToo();
};

typedef Concrete<classOne> classNonAbstractOne; // if desired, for convenience

Make sure to give your abstract base classes either a virtual public destructor or make the destructor protected (then it doesn't have to be virtual, but still can be).

Because the template must be parsed with names looked up without yet knowing exactly what Base will be, you need to either use Base::member or this->member to access inherited members.


I usually try to avoid inheritance if possible (except for pure abstract classes which define pure interfaces) because it creates a tight coupling. In many cases composition is the better alternative.

Also, things tend to get messy with complex inheritance structures. It's not easy to say from your description what's the best in this particular case. Just pointing this out as a rule of thumb.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜