dynamic_cast
OperatorA 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
.
dynamic_cast
sAs 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.
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.
Performing a dynamic_cast
in a condition ensures that the cast and test of its result are done in a single expression.
dynamic_cast
sA 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
}
}