Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ casting programmatically : can it be done?

Tags:

c++

casting

Let's say I have a Base class and several Derived classes. Is there any way to cast an object to one of the derived classes without the need to write something like this :


string typename = typeid(*object).name();
if(typename == "Derived1") {
   Derived1 *d1 = static_cast&lt Derived1*&gt(object);
}
else if(typename == "Derived2") {
   Derived2 *d2 = static_cast &lt Derived2*&gt(object);
}
...
else {
  ...
}
like image 310
Geo Avatar asked Oct 28 '08 12:10

Geo


3 Answers

Don't.

Read up on polymorphism. Almost every "dynamic cast" situation is an example of polymorphism struggling to be implemented.

Whatever decision you're making in the dynamic cast has already been made. Just delegate the real work to the subclasses.

You left out the most important part of your example. The useful, polymorphic work.

string typename = typeid(*object).name();
if(typename == "Derived1") {
   Derived1 *d1 = static_cast< Derived1*>(object);
   d1->doSomethingUseful();
}
else if(typename == "Derived2") {
   Derived2 *d2 = static_cast < Derived2*>(object);
   d2->doSomethingUseful();
}
...
else {
  ...
}

If every subclass implements doSomethingUseful, this is all much simpler. And polymorphic.

object->doSomethingUseful();
like image 129
S.Lott Avatar answered Nov 05 '22 20:11

S.Lott


You can use dynamic_cast and test for NULL, but I'd strongly consider refactoring the code instead.

If you need subclass-specific handling, Template Method might be helpful, but without knowing what you're trying to achive, it's only a vague guess.

like image 9
fhe Avatar answered Nov 05 '22 21:11

fhe


Derived1* d1 = dynamic_cast< Derived1* >(object);
if (d1 == NULL)
{
    Derived2* d2 = dynamic_cast< Derived2* >(object);
    //etc
}

I have the following methods on my smartpointer type, simulating C# 'is' and 'as':

template< class Y > bool is() const throw()
    {return !null() && dynamic_cast< Y* >(ptr) != NULL;}
template< class Y > Y* as() const throw()
    {return null() ? NULL : dynamic_cast< Y* >(ptr);}
like image 5
marijne Avatar answered Nov 05 '22 21:11

marijne