Back to Item 1: Distinguish between pointers and references
Continue to Item 3: Never treat arrays polymorphically

Item 2: Prefer C++-style casts.

Consider the lowly cast. Nearly as much a programming pariah as the `goto`, it nonetheless endures, because when worse comes to worst and push comes to shove, casts can be necessary. Casts are especially necessary when worse comes to worst and push comes to shove.

Still, C-style casts are not all they might be. For one thing, they're rather crude beasts, letting you cast pretty much any type to pretty much any other type. It would be nice to be able to specify more precisely the purpose of each cast. There is a great difference, for example, between a cast that changes a pointer-to-`const`-object into a pointer-to-non-`const`-object (i.e., a cast that changes only the `const`ness of an object) and a cast that changes a pointer-to-base-class-object into a pointer-to-derived-class-object (i.e., a cast that completely changes an object's type). Traditional C-style casts make no such distinctions. (This is hardly a surprise. C-style casts were designed for C, not C++.)

A second problem with casts is that they are hard to find. Syntactically, casts consist of little more than a pair of parentheses and an identifier, and parentheses and identifiers are used everywhere in C++. This makes it tough to answer even the most basic cast-related questions, questions like, "Are any casts used in this program?" That's because human readers are likely to overlook casts, and tools like `grep` cannot distinguish them from non-cast constructs that are syntactically similar.

C++ addresses the shortcomings of C-style casts by introducing four new cast operators, `static_cast`, `const_cast`, `dynamic_cast`, and `reinterpret_cast`. For most purposes, all you need to know about these operators is that what you are accustomed to writing like this,

    (type) expression

you should now generally write like this:

    static_cast<type>(expression)

For example, suppose you'd like to cast an `int` to a `double` to force an expression involving `int`s to yield a floating point value. Using C-style casts, you could do it like this:

    int firstNumber, secondNumber;

    ...

    double result = ((double)firstNumber)/secondNumber;

With the new casts, you'd write it this way:

    double result = static_cast<double>(firstNumber)/secondNumber;

Now there's a cast that's easy to see, both for humans and for programs.

`static_cast` has basically the same power and meaning as the general-purpose C-style cast. It also has the same kind of restrictions. For example, you can't cast a `struct` into an `int` or a `double` into a pointer using `static_cast` any more than you can with a C-style cast. Furthermore, `static_cast` can't remove `const`ness from an expression, because another new cast, `const_cast`, is designed specifically to do that.

The other new C++ casts are used for more restricted purposes. `const_cast` is used to cast away the `const`ness or `volatile`ness of an expression. By using a `const_cast`, you emphasize (to both humans and compilers) that the only thing you want to change through the cast is the `const`ness or `volatile`ness of something. This meaning is enforced by compilers. If you try to employ `const_cast` for anything other than modifying the `const`ness or `volatile`ness of an expression, your cast will be rejected. Here are some examples:

    class Widget { ... };
    class SpecialWidget: public Widget { ... };

    void update(SpecialWidget *psw);

    SpecialWidget sw;                       // sw is a non-const object,
    const SpecialWidget& csw = sw;          // but csw is a reference to
                                            // it as a const object

    update(&csw);            // error! can't pass a const
                             // SpecialWidget* to a function
                             // taking a SpecialWidget*

    update(const_cast<SpecialWidget*>(&csw));
                             // fine, the constness of &csw is
                             // explicitly cast away (and
                             // csw — and sw — may now be
                             // changed inside update)

    update((SpecialWidget*)&csw);
                             // same as above, but using a
                             // harder-to-recognize C-style cast

    Widget *pw = new SpecialWidget;

    update(pw);              // error! pw's type is Widget*, but
                             // update takes a SpecialWidget*

    update(const_cast<SpecialWidget*>(pw));
                             // error! const_cast can be used only
                             // to affect constness or volatileness,
                             // never to cast down the inheritance
                             // hierarch

By far the most common use of `const_cast` is to cast away the `const`ness of an object.

The second specialized type of cast, `dynamic_cast`, is used to perform safe casts down or across an inheritance hierarchy. That is, you use `dynamic_cast` to cast pointers or references to base class objects into pointers or references to derived or sibling base class objects in such a way that you can determine whether the casts succeeded.1 Failed casts are indicated by a null pointer (when casting pointers) or an exception (when casting references):

    Widget *pw;

    ...

    update(dynamic_cast<SpecialWidget*>(pw));
                             // fine, passes to update a pointer
                             // to the SpecialWidget pw points to
                             // if pw really points to one,
                             // otherwise passes the null pointer

    void updateViaRef(SpecialWidget& rsw);

    updateViaRef(dynamic_cast<SpecialWidget&>(*pw));
                             // fine, passes to updateViaRef the
                             // SpecialWidget pw points to if pw
                             // really points to one, otherwise
                             // throws an exception

`dynamic_cast`s are restricted to helping you navigate inheritance hierarchies. They cannot be applied to types lacking virtual functions (see also Item 24), nor can they cast away `const`ness:

    int firstNumber, secondNumber;
    ...
    double result = dynamic_cast<double>(firstNumber)/secondNumber;
                             // error! no inheritance is involved

    const SpecialWidget sw;
    ...
    update(dynamic_cast<SpecialWidget*>(&sw));
                             // error! dynamic_cast can't cast
                             // away constness

If you want to perform a cast on a type where inheritance is not involved, you probably want a `static_cast`. To cast `const`ness away, you always want a `const_cast`.

The last of the four new casting forms is `reinterpret_cast`. This operator is used to perform type conversions whose result is nearly always implementation-defined. As a result, `reinterpret_cast`s are rarely portable.

The most common use of `reinterpret_cast` is to cast between function pointer types. For example, suppose you have an array of pointers to functions of a particular type:

    typedef void (*FuncPtr)();         // a FuncPtr is a pointer
                                       // to a function taking no
                                       // args and returning void

    FuncPtr funcPtrArray[10];          // funcPtrArray is an array
                                       // of 10 FuncPtrs

Let us suppose you wish (for some unfathomable reason) to place a pointer to the following function into `funcPtrArray`:

    int doSomething();

You can't do what you want without a cast, because `doSomething` has the wrong type for `funcPtrArray`. The functions in `funcPtrArray` return `void`, but `doSomething` returns an `int`:

    funcPtrArray[0] = &doSomething;     // error! type mismatch

A `reinterpret_cast` lets you force compilers to see things your way:

    funcPtrArray[0] =                   // this compiles
      reinterpret_cast<FuncPtr>(&doSomething);

Casting function pointers is not portable (C++ offers no guarantee that all function pointers are represented the same way), and in some cases such casts yield incorrect results (see Item 31), so you should avoid casting function pointers unless your back's to the wall and a knife's at your throat. A sharp knife. A very sharp knife.

If your compilers lack support for the new casting forms, you can use traditional casts in place of `static_cast`, `const_cast`, and `reinterpret_cast`. Furthermore, you can use macros to approximate the new syntax:

    #define static_cast(TYPE,EXPR)       ((TYPE)(EXPR))
    #define const_cast(TYPE,EXPR)        ((TYPE)(EXPR))
    #define reinterpret_cast(TYPE,EXPR)  ((TYPE)(EXPR))

You'd use the approximations like this:

    double result = static_cast(double, firstNumber)/secondNumber;

    update(const_cast(SpecialWidget*, &sw));

    funcPtrArray[0] = reinterpret_cast(FuncPtr, &doSomething);

These approximations won't be as safe as the real things, of course, but they will simplify the process of upgrading your code when your compilers support the new casts.

There is no easy way to emulate the behavior of a `dynamic_cast`, but many libraries provide functions to perform safe inheritance-based casts for you. If you lack such functions and you must perform this type of cast, you can fall back on C-style casts for those, too, but then you forego the ability to tell if the casts fail. Needless to say, you can define a macro to look like `dynamic_cast`, just as you can for the other casts:

    #define dynamic_cast(TYPE,EXPR)     (TYPE)(EXPR)

Remember that this approximation is not performing a true `dynamic_cast`; there is no way to tell if the cast fails.

I know, I know, the new casts are ugly and hard to type. If you find them too unpleasant to look at, take solace in the knowledge that C-style casts continue to be valid. However, what the new casts lack in beauty they make up for in precision of meaning and easy recognizability. Programs that use the new casts are easier to parse (both for humans and for tools), and they allow compilers to diagnose casting errors that would otherwise go undetected. These are powerful arguments for abandoning C-style casts, and there may also be a third: perhaps making casts ugly and hard to type is a good thing.

Back to Item 1: Distinguish between pointers and references
Continue to Item 3: Never treat arrays polymorphically

1 A second, unrelated use of `dynamic_cast` is to find the beginning of the memory occupied by an object. We explore that capability in Item 27.
Return