How easy it is to replace the base class
I have the following class hierarchy
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 defines pure virtual methods
class classNonAbstract : public classThree
{
void abstractMethod();
// Couple of new methods
void doIt();
void doItToo();
};
And 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 nonAbstract classes have the same new methods with the same code ... and I would like to avoid copying all the methods and code for each nonAbstract class. How could I do this?
Hope this is clear ...
a source to share
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 your abstract base classes are either a virtual public destructor or protect the destructor (then it doesn't have to be virtual, but it can still be).
Since the template must be handled with the names you were looking for without knowing exactly what Base is, you need to either use Base::member
or this->member
access inherited members.
I usually try to avoid inheritance whenever possible (except for pure abstract classes that define pure interfaces) because it creates tight coupling. In many cases, composition is the best alternative.
Also, things tend to get messy with complex inheritance structures. It is not easy to tell from your description what is best in this particular case. Just pointing it out as a rule.
a source to share