Archived

This topic is now archived and is closed to further replies.

soehrimnir

static_cast, dymanic_cast, ... ??

Recommended Posts

Hi, I''ve seen these casting methods several times in some code I looked through. Can anyone explain to me what the actual difference is between all these casting types? And also, are there even more types then the two I mentioned here? Thanks

Share this post


Link to post
Share on other sites
Have a look in MSDN, they detail what happens quite well.

Basically, a static_case is like a normal C cast, i.e. these two are equivalent:

  
CMyClass *pClass = static_cast<CMyClass *>( pMyOtherClass );
CMyClass *pClass2 = (CMyClass *)pMyOtherClass;


dynamic_cast performs run-time type checks to make sure the types involved can be cast properly. This can only be done if RTTI (Run-Time Type Information) is compiled into your program (it''s not by default in MSVC++).

Another other type of cast is const_case. This is used to remove the const, volatile or __unaligned attributes of a variable.

Finally, the last casting operator is reinterpret_cast. This is the most unsafe conversion operator, since you can convert anything to anything else. The example they give in MSDN is a hashing function, which takes a memory address (via a void pointer), reinterpret_cast''s it to an int and generates a hash.

That''s a brief overview, check MSDN for more details.


codeka.com - Just click it.

Share this post


Link to post
Share on other sites
There is also const_cast and reinterpret_cast.

static_cast: converts between related types
dynamic_cast: converts from base class to derived class for polymorphic types
const_cast: casts away const
reinterpret_cast: generally phucks sh*t up. can convert to anything

DO NOT USE C STYLE CASTS....EVER. IMHO, C style casts shouldn''t have been even included in C++. All of the above casts DO NOT cast away the const of a variable *except* for const_cast.

I think the above can be better explained with examples.

  
float f = 69.0f;
int i = static_cast<int> (f);

const float f1 = 666.0f;
int i1 = static_cast<int> (f1); // errror, i1 is not const

i1 = const_cast<int> f1;

class Poop;
Poop turd;
char * p = reinterpret_cast<char *> (turd);


dynamic_cast is far and away the hardest to understand.

  
class A {};
class B : virtual public A {};
class C : public B {};
class D : public B {};
class E : public C, public D {};

A * p = new E;
E * e;
e = static_cast<E *> (p); // error, no can do

e = dynamic_cast<E *> (p); // that''s better




SL

Share this post


Link to post
Share on other sites
Thank you both for the answers. I understand now.

Just another remark: why is it that I must never use C style casts and use static_cast instead? Since they both accomplish the same task, what could be the problem when doing it the old way?

Share this post


Link to post
Share on other sites
static_cast != C style cast. Not at all. Like Screaming Lunatic said, static_cast can only change to related type :



float j = 3;

int i = static_cast(j); //ok
int i = (int)j; //ok

funkyClass f;

int i = static_cast(funkyClass); //No, not going to do it (unless funkyClass has a conversion operator to int)
int i = (int)f; //ok!



Share this post


Link to post
Share on other sites
static_cast is used for "upcasting". In C++ if you have a class Foo that derives from class Bar then you can do:


pFoo = pBar;

But you can't go the other way (all Bar's are Foo's but the reverse isn't necessarily true.

On the other hand if you've got a pFoo and you somehow know that it really points to a Bar then you can use pBar = static_cast<Bar *>(pFoo).

The reason you use static_cast instead of of a C-style cast is because if for some reason Bar *doesn't* derive from Foo you'll get a compile error.

-Mike

[edit: used proper html for < and >]


Edited by - Magmai Kai Holmlor on November 8, 2001 6:18:19 PM

Share this post


Link to post
Share on other sites
quote:
Original post by Anon Mike
static_cast is used for "upcasting".



Not completly correct. You can also do downcasting with static_cast.

Again : static_cast works on related objects.

So if you have class hierachy where B derives from A, you can do :

  

B b;

A* aPtr = &b;

B* bPtr = static_cast<B*>(a); //valid, A and B are related types




Of course this can lead to problems :

  

A a;

B* bPtr = static_cast<B*>(&a); //Will be accepted by the compiler, but future uses of bPtr are undefined.




Or say we a class C that also derives from A

  

C c;

A* aPtr = &c;

B* bPtr = static_cast<B*>(a); //ok a and b are related but uses of bPtr are undefined


B* bPtr2 = static_cast<B*>(&c); //compiler will complaint. B and C are not related.



So Rule :

You can do downcasting with static_cast if you are absolutely sure that the object you cast will ALWAYS be of the object type you are casting to.

If you are NOT ALWAYS sure, use dynamic_cast and check for NULL.

Share this post


Link to post
Share on other sites