19.2.1. The dynamic_cast Operator

A dynamic_cast has the following form:

dynamic_cast<type*>(e)
dynamic_cast<type&>(e)
dynamic_cast<type&&>(e)

where type must be a class type and (ordinarily) names a class that has virtual functions. In the first case, e must be a valid pointer (§ 2.3.2, p. 52); in the second, e must be an lvalue; and in the third, e must not be an lvalue.

In all cases, the type of e must be either a class type that is publicly derived from the target type, a public base class of the target type, or the same as the target type. If e has one of these types, then the cast will succeed. Otherwise, the cast fails. If a dynamic_cast to a pointer type fails, the result is 0. If a dynamic_cast to a reference type fails, the operator throws an exception of type bad_cast.

Pointer-Type dynamic_casts

As a simple example, assume that Base is a class with at least one virtual function and that class Derived is publicly derived from Base. If we have a pointer to Base named bp, we can cast it, at run time, to a pointer to Derived as follows:

if (Derived *dp = dynamic_cast<Derived*>(bp))
{
    // use the Derived object to which dp points
} else {  // bp points at a Base object
    // use the Base object to which bp points
}

If bp points to a Derived object, then the cast will initialize dp to point to the Derived object to which bp points. In this case, it is safe for the code inside the if to use Derived operations. Otherwise, the result of the cast is 0. If dp is 0, the condition in the if fails. In this case, the else clause does processing appropriate to Base instead.


Image Note

We can do a dynamic_cast on a null pointer; the result is a null pointer of the requested type.


It is worth noting that we defined dp inside the condition. By defining the variable in a condition, we do the cast and corresponding check as a single operation. Moreover, the pointer dp is not accessible outside the if. If the cast fails, then the unbound pointer is not available for use in subsequent code where we might forget to check whether the cast succeeded.


Image Best Practices

Performing a dynamic_cast in a condition ensures that the cast and test of its result are done in a single expression.


Reference-Type dynamic_casts

A dynamic_cast to a reference type differs from a dynamic_cast to a pointer type in how it signals that an error occurred. Because there is no such thing as a null reference, it is not possible to use the same error-reporting strategy for references that is used for pointers. When a cast to a reference type fails, the cast throws a std::bad_cast exception, which is defined in the typeinfo library header.

We can rewrite the previous example to use references as follows:

void f(const Base &b)
{
    try {
        const Derived &d = dynamic_cast<const Derived&>(b);
    // use the Derived object to which b referred
    } catch (bad_cast) {
        // handle the fact that the cast failed
    }
}

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset