Casting in C++

Started by
3 comments, last by ValMan 15 years, 9 months ago
I have a question about casting in C++. I want to cast from a pointer to a base class to a pointer to a derived class. I have a BaseGameState* which holds the currently running state, some derived states have extra functions to pass in data so I would like to cast the BaseGameState* to whatever gamestate is active to then use the functions. I'm sure I've seen reinterpret_cast used for this but I'm not sure and google has left me slightly confused. Am I on the right track? While on the subject, is this a normal thing to do, or maybe a sign of bad design? Thankyou for reading.
Advertisement
If any cast were to be used there, the safest would be dynamic_cast, which requires RTTI (Run Time Type Information) to be enabled at compile time. This guarantees a valid cast if the object is indeed of the type being cast to. reinterpret_cast will work also, without needed RTTI, but is completely "unsafe".

That said, I'm 99% sure that this is a sign of bad design. As a general rule, if you are using inherritance anything that takes a base class should be able to take ANYTHING derived from the base class and function. There are of course the occassional exceptions to this, but this sounds like a case where a little reshuffling might save you a lot of headaches down the line [smile] One simple way I can think of restructuring things given how you've stated them is adding a GetNewData() virtual method to the base class, which the derived classes can use to gather the information it needs.

EDIT: A good line from MSDN on the topic of reinterpret_cast
Quote:The result of a reinterpret_cast cannot safely be used for anything other than being cast back to its original type. Other uses are, at best, nonportable.


EDIT2: Completely forgot that while the cast may be legal, in the vast majority of cases it will not infact point to a valid object.
Quote:Original post by ZeroSum
I have a BaseGameState* which holds the currently running state, some derived states have extra functions to pass in data so I would like to cast the BaseGameState* to whatever gamestate is active to then use the functions.


If the behavior of your code depends on the dynamic type of an object, put that code in a virtual function.

Quote:I'm sure I've seen reinterpret_cast used for this but I'm not sure and google has left me slightly confused. Am I on the right track? While on the subject, is this a normal thing to do, or maybe a sign of bad design?


reinterpret_cast does not work for this, precisely because a pointer to a base class has no reason to be a pointer to a derived class. You can either use static_cast (at which point you have to assume that you are right about the dynamic type of the object) or use dynamic_cast. However, in the overwhelming majority of situations, casting to a derived class pointer is a sign of bad design that could be replaced with virtual functions.
Quote:Original post by ZeroSum

I have a BaseGameState* which holds the currently running state, some derived states have extra functions to pass in data so I would like to cast the BaseGameState* to whatever gamestate is active to then use the functions.


This is the C++ equivalent of passing void * to functions.

The purpose of inheritance is to abstract implementation from interface. If you need to use different interface, polymorphism is wrong choice. Might as well just use different type altogether.

If you need descendants of base class to provide custom functionality, define a virtual function in base class, then override that.

What kind of data are you passing? What are these extra functions? Why are they class-specific?

I would strongly recommend dynamic_cast - I use it all the time and it works great for this. When you try to cast a pointer of base class type to a derived class, and if that pointer is not actually of the type you are casting to, you get a NULL. So that's a guarantee that your code will not crash and be flexible, as long as you handle the NULL case.

This topic is closed to new replies.

Advertisement