-
July 7th, 2000, 07:03 PM
#1
whats up with dynamic_cast, static_cast, and reinterpret_cast?
i don't understand what these do...
dynamic_cast<>
static_cast<>
reinterpret_cast<>
why not just use normal type casting? when i use any of those 3 things, i have compilation problems anyways. thanks for the help. oh yeah, can someone explain to me what the #pragma directive does? thanks!
-christopher bottaro
cjb@cs.utexas.edu
cjb9@mail.utexas.edu
christopher.bottaro@broadwing.com
-
July 7th, 2000, 08:09 PM
#2
Re: whats up with dynamic_cast, static_cast, and reinterpret_cast?
Hi,
reason is: the "normal" cast ( (TYPE) x ) covers four different intentions of casting (that actually do three completely different things on Assembler level). The "C++ style" casts were introduced so the programmer can state what he really wants.
There are the following types of a cast:
* type conversion, like "int" to "float": the _contents_ of the variable will be read and converted (according to some type specific rules)
* casting up in class hierarchy (i.e. cast a dereived class pointer to a base class pointer). On ASM level, usually an offset needs to be added or subtracted from the pointer to the class
* casting down in class hierarchy, i.e. from base to dereived class. This is only safe with run-time information about the class hierarchy, and the "true class" of an object. Again, adding or subtractng an offset from class pointer is necessary
* "hard" cast - treat the data as if it were of different type ("assume the bits at this address are integers"). "Nothing" happens at assembly level (since in machine code, all pointers are void *)
* removing "const" modifiers - again, nothng really happens at assembly (it's only to tell the compiler "I know I break const correctness rules here, please don't complain")
Note that only "hard cast" and "conversion" were possible in classic C, and they could easily be separated (if it's a pointer, it's a "hard" cast).
However, in C++ the ((CFoo *) ptr) can mean a lot of different things, depending on the type of ptr.
Errors introduced by wrongly using the C-style cast operator are notoriously hard to track down.
Now, the real answer:
static_cast does a "safe" type cast, based on the type information available at compile time. static_cast allows type conversion, and casting up in class hierarchy
dynamic_cast does a "safe" type cast, using run time type information, to cast down in class hierarchy. (i.e. it's checked at runtime if the CBase * actually points to a CDereived). For dynamic_cast to work, you must enable RTTI (Run time Type Information) in the C++ compiler settings.
reinterpret_cast does a hard cast - "assume the bits.."
const_cast does the const modifier removal.
-------------
Syntax is:
xxx_cast<destination-type>(expression)
but this of course works only in C++.
-------------
#pragma directives are compiler-specific, they are clearly not part of ANSI or whatever standard. More exactly, the "#pragma" itself is standard, but what follows is compiler-dependent. There are various #pragma directives in MSVC++, from supressing certain warnings to specifying which .lib's the module should be linked to.
Helped?
Peter
P.S. "conversion" cast is not an official or common term; I just used it here since it best describes the action taken
[edited to fix minor typos and a major error]
Last edited by peterchen; November 23rd, 2002 at 04:03 PM.
-
November 20th, 2002, 02:59 PM
#3
So is reinterpret_cast any different from "old" casts?
Eight web pages, and two forum articles still don't really answer the question, although this explanation seems to do it, thanks!
For use with qsort's callback function:
Code:
int myCompare(void *e1, void *e2)
{
MyClass *c1 = *(MyClass **) e1; // Compare is ptr to ptr to object.
MyClass *c2 = *(MyClass **) e2;
return (some comparison code);
}
So would one use reinterpret_cast here? (Pointers are guaranteed to be to the class that is being qsorted in the array, not any derived or parent version, i.e. it's an array of MyClasses, not of any parent or child of them.)
And: given it's void, wouldn't the old-style cast be acceptable?
-
November 20th, 2002, 04:03 PM
#4
Check this forum thread for answers:
http://www.codeguru.com/forum/showth...einterpretcast
and yes. reinterpret_cast is exactly the same as the old C cast.
Last edited by proxima centaur; November 20th, 2002 at 04:06 PM.
Martin Breton
3D vision software developer and system integrator.
-
November 20th, 2002, 05:54 PM
#5
Re: So is reinterpret_cast any different from "old" casts?
Originally posted by Gorgor
For use with qsort's callback function:So would one use reinterpret_cast here? (Pointers are guaranteed to be to the class that is being qsorted in the array, not any derived or parent version, i.e. it's an array of MyClasses, not of any parent or child of them.)
Oh no!
So you are calling qsort() on an array of MyClasses or pointers to them? If it is an array of MyClasses, qsort() can only be guaranteed to work if MyClasses is a POD (Plain-Old-Data) class (i.e. it is a struct or class consisting of int's doubles, chars, pointers, arrays of these things, etc.). If it contains non-POD items like std::string, CList, vector, etc. or non-trivial constructors, destructors, etc., qsort is not guaranteed to work. Use std::sort to sort objects correctly, not qsort. Not only that, the ugly pointer code you're doing now with qsort would be a thing of the past.
There was a long thread on this in the non-Visual C++ group -- qsort is not guaranteed to sort an array of non-POD objects correctly. As a matter of fact, it totally messed up an array of objects when tested on several compilers, while std::sort worked perfectly.
Regards,
Paul McKenzie
-
November 20th, 2002, 06:10 PM
#6
Re: Re: whats up with dynamic_cast, static_cast, and reinterpret_cast?
Originally posted by peterchen
Hi,
* casting up in class hierarchy (i.e. cast a dereived class pointer to a base class pointer). Typically, an offset needs to be added or subtracted from the pointer to the class
* casting down in class hierarchy, i.e. from base to dereived class. This is only safe with run-time information about the class hierarchy. Again, adding or subtractng an offset from class pointer is necessary
Can you give me some more information about this offset.
thanks
-
November 23rd, 2002, 04:37 PM
#7
Gorgor: Thanks! It's always nice to hear a post has been helpful, especially if it's 2 years old....
souldog:
all this is very compiler-dependent, but there's a "normal" implementation, at least for single-inheritance-hierarchies.
imagine two classes
class CAlpha
{
public: int a;
};
class CBeta : public CAlpha
{
public: int b;
};
class CGamma : public CBeta
{
public: int c;
};
(Only data members matter for the discussion, as member functions don't require per-instance data)
So an instance of of CGamma would be layed out like this (the base address is meaningless, just as an example):
Code:
[0x100] CGamma * ---> CGamma.c
[0x104] CBeta * ---> CBeta.b
[0x108] CAlpha * ---> CAlpha.a
so if you cast from CAlpha to CBeta, the compiler will subtract 4 from the pointer.
You can reverse the stack (only accesisng the class members gets weirder on ASM level).
If you have multiple inheritance, things get much more tricky, but in general, it's possible in a similar way.
-
November 23rd, 2002, 04:45 PM
#8
Thanks Peter, that was helpful
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|