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





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