The fourth and last C++ cast is dynamic_cast.
This one is only used to convert object pointers
and object references into other pointer or
reference types in the inheritance hierarchy.
It is the only cast that makes sure that the
object pointed to can be converted, by performing
a runtime check that the pointer refers to
a complete object of the destination type.
For this runtime check to be possible the
object must be polymorphic. That is, the class
must define or inherit at least one virtual
function, because the compiler will only generate
the needed runtime type information for such
objects.
In the first example we convert a MyChild
pointer into a MyBase pointer using a dynamic_cast.
This derived-to-base conversion succeeds,
because the Child object includes a complete
Base object. In the next example we instead
attempt to convert a MyBase pointer to a MyChild
pointer. Since the Base object does not contain
a complete Child object this pointer conversion
will fail, and to indicate this the dynamic_cast
returns a null pointer. This gives us a convenient
way to check if a conversion has succeeded
or not during run-time. If we did not convert
a pointer but a reference instead the dynamic_cast
would then fail by throwing a bad_cast exception,
which we would need to handle using a try-catch
statement.
Note that the advantage of using a dynamic_cast
is that it allows us to check if a conversion
has succeeded during run-time. The disadvantage
is that there is a performance overhead associated
with this doing this check. For this reason
using a static_cast would have been preferable
in the first example, because a derived-to-base
conversion will never fail. However, in the
second example, the conversion may either
succeed or fail. It will fail if the MyBase
object contains a MyBase instance and it will
succeed if it contains a MyChild instance.
In some situations we may not know which one
it contains until runtime. In that case dynamic_cast
a better choice than static_cast.
If we had performed this base-to-derived conversion
using a static_cast instead of a dynamic_cast
the conversion would not have failed. It would
have returned a pointer that refered to an
incomplete object, and dereferencing such
a pointer can lead to runtime errors.
