Reputation: 4022
I've posted about this problem before (Here), this is a different approach to a solution. This solution to be seems to better encapsulate the behavior for those implementing the class, since it prevents them from needing to explicitly up cast.
Here's the problem:
I have a project in which I want to isolate core behavior in most objects, while providing additional behavior through derived objects. Simple enough:
class BaseA
{
virtual void something() {}
}
class DerivedA : public BaseA
{
void something() {}
void somethingElse() {}
}
Now let’s say I also have a second set of classes, same inheritance scheme except that they aggregate the above classes. However, I would like the base version to use the base class, and the derived version in the derived class. My solution i was thinking about 'hiding' the base class variable by using the same name;
class BaseB
{
BaseA *var;
BaseB()
{
var = new BaseA();
}
virtual void anotherThing1();
virtual void anotherThing2();
virtual void anotherThing3();
}
class DerivedB : public BaseB
{
DerivedA *var;
DerivedB()
{
var = new DerivedA();
}
void anotherThing1();
void anotherThing2();
void anotherThing3();
void andAnother1();
void andAnother2();
}
The goal for this approach is so that functions that rely on the derived aggregated class no longer need to explicitly cast to achieve the gained functionality.
void func1( BaseB &b )
{
b.anotherThing1();
b.var->something();
}
void func2( DerivedB &b )
{
b.anotherThing1();
b.andAnother1();
b.var->something();
b.var->somethingElse();
}
void main( int argc, char **argv )
{
BaseB baseB;
DerivedB derivedB;
func1( baseB );
func1( derivedB );
func2( derivedB );
}
Would this be considered bad practice?
Upvotes: 2
Views: 2622
Reputation: 726559
Would this be considered bad practice?
Yes, it would be bad practice, because the var
in the Base
would be unused. It does not look like DerivedB
should be deriving from BaseB
: instead, they should be derived from the same abstract base class, like this:
class AbstractB {
public:
virtual void anotherThing1() = 0;
virtual void anotherThing2() = 0;
virtual void anotherThing3() = 0;
};
class DerivedB1 : public AbstractB { // Former BaseB
BaseA *var;
public:
DerivedB1() {
var = new BaseA();
}
virtual void anotherThing1();
virtual void anotherThing2();
virtual void anotherThing3();
};
class DerivedB2 : public AbstractB { // Former DerivedB
DerivedA *var;
public:
DerivedB2() {
var = new DerivedA();
}
void anotherThing1();
void anotherThing2();
void anotherThing3();
void andAnother1();
void andAnother2();
};
General principle in use here is that you should try making all your non-leaf classes in your inheritance hierarchy abstract.
Upvotes: 1