views:

3006

answers:

8

We often hear/read that one should avoid dynamic casting. I was wondering what would be 'good use' examples of it, according to you?

Edit:

@Sam: yes, I'm aware of that other thread: it is indeed when reading one of the first answers there that I asked my question!

A: 

My current toy project uses dynamic_cast twice; once to work around the lack of multiple dispatch in C++ (it's a visitor-style system that could use multiple dispatch instead of the dynamic_casts), and once to special-case a specific subtype.

Both of these are acceptable, in my view, though the former at least stems from a language deficit. I think this may be a common situation, in fact; most dynamic_casts (and a great many "design patterns" in general) are workarounds for specific language flaws rather than something that aim for.

DrPizza
A: 

The other thread isn't really asking the same question.

DrPizza
A: 

It can be used for a bit of run-time type-safety when exposing handles to objects though a C interface. Have all the exposed classes inherit from a common base class. When accepting a handle to a function, first cast to the base class, then dynamic cast to the class you're expecting. If they passed in a non-sensical handle, you'll get an exception when the run-time can't find the rtti. If they passed in a valid handle of the wrong type, you get a NULL pointer and can throw your own exception. If they passed in the correct pointer, you're good to go. This isn't fool-proof, but it is certainly better at catching mistaken calls to the libraries than a straight reinterpret cast from a handle, and waiting until some data gets mysteriously corrupted when you pass the wrong handle in.

Eclipse
+1  A: 

Here's something I do often, it's not pretty, but it's simple and useful.

I often work with template containers that implement an interface, imagine something like

template<class T>
class MyVector : public ContainerInterface
...

Where ContainerInterface has basic useful stuff, but that's all. If I want a specific algorithm on vectors of integers without exposing my template implementation, it is useful to accept the interface objects and dynamic_cast it down to MyVector in the implementation. Example:

// function prototype (public API, in the header file)
void ProcessVector( ContainerInterface& vecIfce );

// function implementation (private, in the .cpp file)
void ProcessVector( ContainerInterface& vecIfce)
{
    MyVector<int>& vecInt = dynamic_cast<MyVector<int> >(vecIfce); 
    // the cast throws bad_cast in case of error but you could use a
    // more complex method to choose which low-level implementation
    // to use, basically rolling by hand your own polymorphism.

    // Process a vector of integers
    ...
}

I could add a Process() method to the ContainerInterface that would be polymorphically resolved, it would be a nicer OOP method, but I sometimes prefer to do it this way. When you have simple containers, a lot of algorithms and you want to keep your implementation hidden, dynamic_cast offers an easy and ugly solution.

You could also look at double-dispatch techniques.

HTH

rlerallut
A: 

Well it would really be nice with extension methods in C#.

For example let's say I have a list of objects and I want to get a list of all ids from them. I can step through them all and pull them out but I would like to segment out that code for reuse.

so something like

List<myObject> myObjectList = getMyObjects();

List<string> ids = myObjectList.PropertyList("id");

would be cool except on the extension method you won't know the type that is coming in.

So

public static List<string> PropertyList(this object objList, string propName) {
    var genList = (objList.GetType())objList;
}

would be awesome.

+3  A: 

This recent thread gives an example of where it comes in handy. There is a base Shape class and classes Circle and Rectangle derived from it. In testing for equality, it is obvious that a Circle cannot be equal to a Rectangle and it would be a disaster to try to compare them. While iterating through a collection of pointers to Shapes, dynamic_cast does double duty, telling you if the shapes are comparable and giving you the proper objects to do the comparison on.

http://stackoverflow.com/questions/301959/vector-iterator-not-dereferencable

Mark Ransom
A: 

Can you quote some examples of where or why dynamic_cast is considered "bad"?

I've always thought it was full of type-safe goodness...

Roddy
It's about 10,000 times slower than a static_cast. A static cast might have to adjust the pointer to another class: one instruction. A dynamic_cast might have to scan string tables of class names: ten thousand instructions.
Zan Lynx
class name string tables? Surely it's just working with VMT pointers...??? Well, I guess I need to measure it...
Roddy
A reference here: http://www.gamedev.net/community/forums/topic.asp?topic_id=508788 and here: http://stackoverflow.com/questions/579887/how-expensive-is-rtti
Zan Lynx