Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Practical use of dynamic_cast?

Tags:

c++

casting

rtti

I have a pretty simple question about the dynamic_cast operator. I know this is used for run time type identification, i.e., to know about the object type at run time. But from your programming experience, can you please give a real scenario where you had to use this operator? What were the difficulties without using it?

like image 589
cexplorer Avatar asked Aug 01 '12 13:08

cexplorer


People also ask

What is the use of dynamic_cast?

The primary purpose for the dynamic_cast operator is to perform type-safe downcasts. A downcast is the conversion of a pointer or reference to a class A to a pointer or reference to a class B , where class A is a base class of B .

Should I use dynamic_cast?

This cast is used for handling polymorphism. You only need to use it when you're casting to a derived class. This is exclusively to be used in inheritence when you cast from base class to derived class.

What is the difference between Static_cast and dynamic_cast?

static_cast − This is used for the normal/ordinary type conversion. This is also the cast responsible for implicit type coersion and can also be called explicitly. You should use it in cases like converting float to int, char to int, etc. dynamic_cast −This cast is used for handling polymorphism.

Is dynamic_cast a code smell?

Yes, dynamic_cast is a code smell, but so is adding functions that try to make it look like you have a good polymorphic interface but are actually equal to a dynamic_cast i.e. stuff like can_put_on_board .


2 Answers

Toy example

Noah's ark shall function as a container for different types of animals. As the ark itself is not concerned about the difference between monkeys, penguins, and mosquitoes, you define a class Animal, derive the classes Monkey, Penguin, and Mosquito from it, and store each of them as an Animal in the ark.

Once the flood is over, Noah wants to distribute animals across earth to the places where they belong and hence needs additional knowledge about the generic animals stored in his ark. As one example, he can now try to dynamic_cast<> each animal to a Penguin in order to figure out which of the animals are penguins to be released in the Antarctic and which are not.

Real life example

We implemented an event monitoring framework, where an application would store runtime-generated events in a list. Event monitors would go through this list and examine those specific events they were interested in. Event types were OS-level things such as SYSCALL, FUNCTIONCALL, and INTERRUPT.

Here, we stored all our specific events in a generic list of Event instances. Monitors would then iterate over this list and dynamic_cast<> the events they saw to those types they were interested in. All others (those that raise an exception) are ignored.

Question: Why can't you have a separate list for each event type?

Answer: You can do this, but it makes extending the system with new events as well as new monitors (aggregating multiple event types) harder, because everyone needs to be aware of the respective lists to check for.

like image 56
BjoernD Avatar answered Sep 29 '22 08:09

BjoernD


A typical use case is the visitor pattern:

struct Element {     virtual ~Element() { }      void accept(Visitor & v)     {         v.visit(this);     } };  struct Visitor {     virtual void visit(Element * e) = 0;     virtual ~Visitor() { } };   struct RedElement : Element { }; struct BlueElement : Element { }; struct FifthElement : Element { };   struct MyVisitor : Visitor {     virtual void visit(Element * e)     {         if (RedElement * p = dynamic_cast<RedElement*>(e))         {              // do things specific to Red         }         else if (BlueElement * p = dynamic_cast<BlueElement*>(e))         {              // do things specific to Blue         }         else         {              // error: visitor doesn't know what to do with this element         }     } }; 

Now if you have some Element & e;, you can make MyVisitor v; and say e.accept(v).

The key design feature is that if you modify your Element hierarchy, you only have to edit your visitors. The pattern is still fairly complex, and only recommended if you have a very stable class hierarchy of Elements.

like image 35
Kerrek SB Avatar answered Sep 29 '22 06:09

Kerrek SB