Reputation: 21
I am working on a c++ project, and facing a design issue currently. I would appreciate it if someone can give me some suggestions. Basically, I have a base class Base, and a subclass Derived as below. Class Derived can do something that class Base cannot do.
class Base
{
public:
virtual bool IsCapableOfDoingA() {return false;}
}
class Derived: public Base
{
public:
bool IsCapableOfDoingA() {return true;}
void DoA();
}
In another place where I have a pointer of type class Base.
void functionA(Base *pBase)
{
if (pBase && pBase->IsCapableOfDoingA())
{
Derived *pDerived = static_cast<Derived*>(pBase);
pDerived->DoA();
}
}
Upvotes: 0
Views: 1184
Reputation: 308158
Here's another idea. You can split the enhanced functions into an interface and have a method to return the interface pointer.
class InterfaceA
{
public:
virtual ~InterfaceA() {}
virtual void DoA() = 0;
};
class Base
{
public:
virtual InterfaceA* GetAInterface() {return NULL;}
};
class Derived: public Base, InterfaceA
{
public:
InterfaceA* GetAInterface() {return this;}
void DoA();
};
void functionA(Base *pBase)
{
InterfaceA* pA = pBase ? pBase->GetAInterface() : NULL;
if (pA)
pA->DoA();
}
Upvotes: 0
Reputation: 35188
In your design, is it ok for DoA
to return a success code of some sort? You could replace IsCapableOfDoingA
with DoA
itself, and have the Base version simply return false (or other suitable error code). Child objects capable of doing A
can override this function with a proper implementation.
You're right that dynamic_cast
is often a design smell. With some more context we might be able to provide a better answer. My first thought is to really make sure a Derived
IS-A Base
if you're going to be polymorphically asking Base
s for things they might not be able to do.
Upvotes: 2
Reputation: 15944
dynamic_cast will return NULL if the object doesn't have the appropriate type (assuming that the base class defines at least one virtual method -- usually you should at least make the base class's destructor virtual). So you can use the following idiom:
void functionA(Base *pBase)
{
if (Derived *pDerived = dynamic_cast<Derived*>(pBase)) {
pDerived->DoA();
}
}
If pBase doesn't have type Derived, then pDerived will be 0 (false), so the body of the if statement will be skipped.
Upvotes: 1
Reputation: 308158
The usual way is to add the function to the base class.
virtual void DoA() { throw std::runtime_error("Not implemented"); }
Upvotes: 4