Hello all I have this example. Usually in this case I would use Visitor pattern. However for some reason the person who wrote Base
, DerivedA
, DerivedB
prefers dynamic_cast
s. Keep in mind that I can not change Base
, DerivedA
, DerivedB
classes.
I have got around casting with partial specialization. Please let me know if this is a good solution or there is a better one?
#include <iostream>
using namespace std;
class CBase{};
class CDerivedA: public CBase{};
class CDerivedB : public CBase{};
class CDerivedC : public CBase{};
template <typename T>
void Draw(T* face)
{
cout<<"Base"<<endl;
}
template <>
void Draw<>(CDerivedA* face)
{
cout<<"A"<<endl;
}
template <>
void Draw<>(CDerivedB* face)
{
cout<<"B"<<endl;
}
int main() {
CDerivedA* a = new CDerivedA ();
CDerivedB* b = new CDerivedB ();
CDerivedC* c = new CDerivedC ();
Draw(a);
Draw(b);
Draw(c);
return 0;
}
If the types are known at compile time, you can simply use function overloading. This also works in addition to a base class overload (or a generic function template if needed).
void Draw(CBase* face);
void Draw(CDerivedA* face);
void Draw(CDerivedB* face);
If the types are known at runtime, and you have no option to modify the classes (i.e. add virtual functions), you need some kind of dispatching mechanism. An approach that doesn't involve a lot of classes and boilerplate code would be a table mapping types to functions, e.g. std::map<std::type_index, std::function<void()>>
or similar. It may not be as efficient because of the lookup and dynamic dispatch overhead.