Let's say I have the following class hierarchy:
class A
{
public:
virtual ~A();
};
class B : public A
{};
class AUser
{
public:
virtual ~AUser();
protected:
A* m_pA;
};
class BUser : public AUser
{};
Now I want to add a method to B
which is not relevant for A
and will be called only from BUser
.
class B : public A
{
public:
void addedFunctionality()
{
// do something
}
};
To call the added method I have two options:
Add an empty method to A:
class A
{
public:
virtual ~A();
void addedFunctionality()
{
// do nothing
}
};
class BUser : public AUser
{
void useB()
{
m_pA->addedFunctionality();
}
};
call the added method using downcast:
class BUser : public AUser
{
void useB()
{
static_cast<B*>(m_pA)->addedFunctionality();
}
};
I know downcasts should be avoided but I don't like the first option as it bloats A
's code for no reason.
Is there any other design alternative?
The simplest solution looks like this (also suggested by Ulrich Eckhardt):
class AUser
{
public:
AUser(A* a)
{
m_pA = a;
}
protected:
A* m_pA;
};
class BUser : public AUser
{
public:
BUser(B* b) : AUser(b)
{
m_pB = b;
}
void useB()
{
m_pB->addedFunctionality();
}
protected:
B* m_pB;
};
Less clean, but you may also consider this:
class BUser : public AUser
{
public:
BUser(B* b) : AUser(b)
{
}
void useB()
{
getB()->addedFunctionality();
}
protected:
B *getB()
{
return dynamic_cast<B*>(m_pA);
}
};