Introduction
(To keep the interest flowing, I have interjected the article with some trivia. Like this-The name trivia comes from a Latin word which means a place where three roads meet. Such a place is where people would gather to discuss mundane stuff; Interesting but not essential.)
Underneath the calm exteriors of casting, lies the turbulent uncertainty (Heisenberg, famous for his uncertainty principle, has the epitaph, albeit unofficial, which reads "He lies somewhere here") of which to use when. Truth is the name says it all. But of course, there is always something in the name (To counter Intel, the then Superman of processor industry, AMD introduced the K-series of processors. Why ‘K’? The ‘K’ stood for Krypton, the only weapon known to defeat Superman). To know more on casting, read on.
Using the Code
TICS says reinterpret_cast
is a no-no. Why exactly?
To take a page from Rowling’s Potter, reinterpret_cast
is the wizard that could cast a spell to turn an object into any other. There is no compile time or run time checks on the safety of this casting. The compiler assumes that the conversion is valid and force casts the object. Ergo, it is not safe! ("Cogito ergo sum" proposed by Rene Descartes translates to I Think Therefore I Am and is the inspiration behind the company ITTIAM, founded by Srini Rajan).
class A{
public: <methods>; private: int i; };
class B{
public: <methods>; private: string s; }
B* =
reinterpret_cast*lt;B*>(new A());
So, is dynamic_cast
my next best choice, since I am dealing here with pointers?
It is not true that if it is pointers, one has to use dynamic_cast
. Use of static_cast
is perfectly normal for pointer conversions between polymorphic types, both up and down casting. So, if we take the earlier code excerpt and use static_cast
instead of reinterpret_cast
, there would be a compile time error.
B* =
static_cast<B*>(new A());
If static_cast
is good enough, why is there a dynamic_cast
at all?
To answer this question, let us take a step back to understand polymorphic types. Look at the excerpt of code that follows:
void Minds(
A* input) {….}
Though input is of type pointer to A at compile time, it may point to a different type at run time. Of course not just any type, but one of the polymorphic types of A. Two types A and B are said to be polymorphic if they are related somewhere along the inheritance hierarchy. (In the world of chatting, the phrase ABAAABABB is meant to imply ‘Long time no C’ – ‘Long time no see’)
Now, let us assume the following scenario:
class AChild
: public A {
…
};
void
SomeMethod() {
Minds( new A()); A and pass to the method ‘Minds()’.
void Minds(
A* input) {
AChild* local_input = static_cast<AChild*>(input);
}
The above piece of code will compile perfectly fine, but at run time the behavior is unpredictable. And this is where the static_cast
falls short of expectations and hence considered unsafe.
So, is this where a dynamic_cast
comes in?
Precisely, unlike a static_cast
that does only compile time checking; a dynamic_cast
cast does run time checks. So the above piece of code when changed to use a dynamic_cast
,
void Minds(
A* input) {
AChild* local_input = dynamic_cast<AChild*>(input);
if( local_input != null ) { …. }
}
would not result in unpredictable behavior but would instead return a null
if the casting is incorrect. As you can see, dynamic_cast
gives us a more graceful error handling through null
-returns. Note however that if a reference is used instead of a pointer, dynamic_cast
would throw an exception in the event of a failed casting.
I hope this gives a few hints of which casts to use when, if not, there is always Google. (According to a myth, Apple’s logo containing a half eaten apple with rainbow colors is a dedication to Alan Turing; the half eaten apple is because Turing killed himself by eating a poisoned apple. As for the rainbow colors, I will leave that for you to figure out. Remember, there is always Google!)