Important alert: (current site time 7/15/2013 4:45:29 PM EDT)
 

article

Casts Made Easy!

Email
Submitted on: 12/27/2001 2:38:50 PM
By: Andrew Hull 
Level: Intermediate
User Rating: By 14 Users
Compatibility: C++ (general), Microsoft Visual C++, Borland C++, UNIX C++
Views: 23032
(About the author)
 
     A tutorial that explains and gives examples for static_cast, reinterpret_cast, const_cast, and dynamic_cast.

 
 
Terms of Agreement:   
By using this article, you agree to the following terms...   
  1. You may use this article in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
  2. You MAY NOT redistribute this article (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.   
  3. You may link to this article from another website, but ONLY if it is not wrapped in a frame. 
  4. You will abide by any additional copyright restrictions which the author may have placed in the article or article's description.
				

Casts Made Easy!

 

In C, casting was easy. You could cast like you called a function:

int i = int('A');

You can also do this in C++. But the only reason it's there is for backwards compatibility with C. Casting like this will eventually cause havoc in a large program, and it also only provides support for primitive types. In C++, there is a set of 4 ANSI C++ casts: static_cast, reinterpret_cast, const_cast, and (the much feared) dynamic_cast. Here I will provide an explanation and example for each cast, to make them easier to understand and possibly save some programs using C casting :)


First, the simplest and most common, static_cast. This cast simply converts from one data type to another. The syntax is:

static_cast<new_type>(argument);

where new_type is the type to be converted to, and argument is the data you wish to convert. Converting my earlier example from C to C++ yields:

int i = static_cast<int>('A');

Note that new_type can be any data type, primitive or user-defined. argument can also be a variable:

char letter = 'A';
int i = static_cast<int>(letter);

That's all there really is to static_cast.


The next type of (and hardest to spell) cast is reinterpret_cast. Unlike static_cast, reinterpret_cast doesn't actually change any data, it causes the data to be reinterpreted, or looked at differently, by the compiler. The most common use of reinterpret_cast is casting a void* pointer, such as the one returned from malloc():

int* num = reinterpret_cast<int*>(malloc(100));

But then again, who needs malloc() when you've got new? reinterpret_cast can be dangerous, however, like in this example:

int num = 5;
int* pNum = &num;
double* pDouble = reinterpret_cast<double*>(pNum);

cout << *pDouble << endl;

This outputs integer data as if it were double (or floating point) data. Nothing but bad things can result from that! You'll probably get a lot of garbage printed to the screen.

The moral here? Be careful with reinterpret_cast!


Next we'll look at const_cast. const_cast is for adding/removing const from a variable. There usually isn't a reason to do this, and if there is, it's probably bad programming. However, every so often there's a situation that you just can't get around, and have to use const_cast. (sorta like goto). Here's a simple example:

void Display(int* data)
{
cout << *data << endl;
}

int main()
{
const int num = 5;
Display(const_cast<int*>(&num));

return 0;
}

If you don't use const_cast here, the compiler will give you an error along the lines of "no match for function..." because const data can't be passed into non-const function data. Redundant? Yes. Avoidable? Yes. Occasionally necessary? Yes.


Finally, it's time to tackle the one no one else wants to: dynamic_cast. There's a lot of confusion over what it does, why to use it, when to use it, etc. The formal (i.e. newbie-scaring) description says that it "is a polymorphic cast that verifies the runtime type of the object being cast". Ouch. To make it clearer, consider this example:

class Base
{
public
virtual void DoSomething() {cout << "Base" << endl;}
};

class Derived : public Base
{
public:
virtual void DoSomething() {cout << "Derived" << endl;}
};

int main()
{
Derived derived;
Base* pBase = &derived;
// the base pointer points to a derived object. Legal, but confusing.

Derived* pDerived = dynamic_cast<Derived*>(pBase);
// because pBase is actually a pointer to a Derived at runtime, the
// cast succeeds and pDerived is assigned the value of pBase

if (pDerived)
pDerived->DoSomething();

else
cout << "Bad cast" << endl;

return 0;
}

 

In this example, the pointer to Base was assigned the address of a Derived object. That's legal. Then, a pointer to a Derived is declared. A check is performed with dynamic_cast: if, at runtime, the argument (pBase) is of type new_type (Derived), then dynamic_cast returns a pointer to Derived with the value pBase. So, pDerived is assigned the value of a base pointer which without a cast would be impossible.

dynamic_cast returns NULL if the cast fails, so to prevent a memory leak ALWAYS check if the cast succeeded with an if...else. Classes used with dynamic_cast must have at least one virtual function.


Well, that's it. I hope you've learned something from all of this! Please leave any comments/feedback that come to mind, everything is appreciated! If you need anything cleared up, please feel free to email me at kavutitan26@yahoo.com. Enjoy!

->Andrew-<


Other 3 submission(s) by this author

 


Report Bad Submission
Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
This submission should be removed because:

Your Vote

What do you think of this article (in the Intermediate category)?
(The article with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor (See voting log ...)
 

Other User Comments
12/27/2001 3:22:43 PMJared Bruni

Good article , 5 globes
(If this comment was disrespectful, please report it.)

 
12/27/2001 8:11:44 PMDaniel West

useful, but i still dont understand dynamic_cast. email me.
(If this comment was disrespectful, please report it.)

 
12/28/2001 10:41:44 AMtrowone

nice job, Andrew. The code snippets always help when explaining a topic. Explanations are clear and concise, perfect.
(If this comment was disrespectful, please report it.)

 

Add Your Feedback
Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular article, please click here instead.)
 

To post feedback, first please login.