Главная страница | назад





Article #17345: Casting operators

 Question and Answer Database
FAQ2345C.txt Casting operators
Category :C/C++ Language Issues
Platform :All
Product :C++Builder ALL
Question:
Which casting operator should I use?
Answer:
conversions from user defined types (classes, structs,
etc.) may be more complex than a simple C-style cast
can provide for
the syntax is "harder" to type than C style casts, the
intent here is to reinforce the idea that casts are
generally due to a design flaw.
they are more explicit than C style casts. They
communicate the programmer's intent better than the
old C-style casts.
Here's a run-down on the casting operators and when you would use them.
dynamic_cast
Generally resolved at run-time.
Used primarily to cast pointers and references to
(polymorphic) classes, generally up, down and across
class hierarchies. (A polymorphic class is one that
has at least one virtual method).
If the desired type is a pointers, and the cast cannot
be made (i.e., the source type is not a pointer, the
classes are not related by one or more common bases,
nor is there a well defined conversion from the source
type to the target type), the result of the dynamic_cast
is a NULL pointer. Otherwise, dynamic_cast returns
a pointer to the desired type.
If the desired type is a reference, and the cast cannot
be made, the exception std::bad_cast is thrown. If
the cast can be made, dynamic_cast returns a reference
to the desired type.
Note also that the check whether this cast can succeed
occurs at run-time.
See section 5.2.7 of the standard for more precise
legaleze.
static_cast
Generally resolved at compile time.
used to cast most other types. For this one, it's
easier to say what *cannot* be cast using this operator:
static_cast will *not* cast:
 — pointers to non-pointers, and vice versa (a non-pointer
can be cast to a pointer if the non-pointer is a class
type that defines the appropriate conversion(s),
though).
 — const to non-const, and vice versa (use const_cast)
 — pointer to array (the inverse, array to pointer,
is a standard, implicit conversion, though)
 — pointer to function (the inverse, function to pointer
is a standard, implicit conversion)
 — pointer/reference to virtual base to p/r to derived
(use dynamic_cast)
 — bool to anything else (although the inverse, X to bool,
is usually an implicit cast for built-in types).
The compiler uses its knowledge of the underlying types
to insure that the cast is correct, offsetting pointers
if necessary.
see section 5.2.9
reinterpret_cast
Resolved at compile time.
Used for all those situations when dynamic_cast or
static_cast won't work (although it still doesn't cast
away constness). Generally it tells the compiler to
view the bits of the argument type as if they actually
composed the target type (usually this occurs in place:
no offset correction will be done, although the standard
leaves that open, with it's "implementation defined"
weasel clause). This operator is *almost* identical to
the old C style casts.
See section 5.2.10
const_cast
Used to cast away the const and/or volatile modifier
on a variable.
See section 5.2.11
More so, yes. The other reasons given are:
conversions from user defined types (classes, structs,
etc.) may be more complex than a simple C-style cast
can provide for
the syntax is "harder" to type than C style casts, the
intent here is to reinforce the idea that casts are
generally due to a design flaw.
they are more explicit than C style casts. They
communicate the programmer's intent better than the
old C-style casts.
Here's a run-down on the casting operators and when you would use them.
dynamic_cast
Generally resolved at run-time.
Used primarily to cast pointers and references to
(polymorphic) classes, generally up, down and across
class hierarchies. (A polymorphic class is one that
has at least one virtual method).
If the desired type is a pointers, and the cast cannot
be made (i.e., the source type is not a pointer, the
classes are not related by one or more common bases,
nor is there a well defined conversion from the source
type to the target type), the result of the dynamic_cast
is a NULL pointer. Otherwise, dynamic_cast returns
a pointer to the desired type.
If the desired type is a reference, and the cast cannot
be made, the exception std::bad_cast is thrown. If
the cast can be made, dynamic_cast returns a reference
to the desired type.
Note also that the check whether this cast can succeed
occurs at run-time.
See section 5.2.7 of the standard for more precise
legaleze.
static_cast
Generally resolved at compile time.
used to cast most other types. For this one, it's
easier to say what *cannot* be cast using this operator:
static_cast will *not* cast:
 — pointers to non-pointers, and vice versa (a non-pointer
can be cast to a pointer if the non-pointer is a class
type that defines the appropriate conversion(s),
though).
 — const to non-const, and vice versa (use const_cast)
 — pointer to array (the inverse, array to pointer,
is a standard, implicit conversion, though)
 — pointer to function (the inverse, function to pointer
is a standard, implicit conversion)
 — pointer/reference to virtual base to p/r to derived
(use dynamic_cast)
 — bool to anything else (although the inverse, X to bool,
is usually an implicit cast for built-in types).
The compiler uses its knowledge of the underlying types
to insure that the cast is correct, offsetting pointers
if necessary.
see section 5.2.9
reinterpret_cast
Resolved at compile time.
Used for all those situations when dynamic_cast or
static_cast won't work (although it still doesn't cast
away constness). Generally it tells the compiler to
view the bits of the argument type as if they actually
composed the target type (usually this occurs in place:
no offset correction will be done, although the standard
leaves that open, with it's "implementation defined"
weasel clause). This operator is *almost* identical to
the old C style casts.
See section 5.2.10
const_cast
Used to cast away the const and/or volatile modifier
on a variable.
See section 5.2.11
7/2/98 10:32:32 AM

Last Modified: 01-SEP-99