dynamic_cast
works differently from static_cast
. The results of a static_cast
are always a pointer. However, if the cast is incorrect (to a type that the given pointer wasn't originally), then the result of the cast is undefined; the pointer is not necessarily valid. Thus, there is some degree of uncertainty when casting to derived classes with static_cast
; there is no mechanism to prevent you from casting to the wrong things.
dynamic_cast
will return either a valid pointer if the cast is correct, or a null pointer if it is incorrect. Thus, the results are well-defined in all cases. In order to do this, dynamic_cast
must be dynamic. This means that it has to do runtime checks on the pointer to see if the type being cast to is a legal cast operation.
C++ forbids casts for non-virtual types due to the "pay for what you use" principle: a type that doesn't have virtual functions is generally not a type that you're passing around by its base classes. Inheritance without virtuals is primarily about using the existing implementation, not about specializing functions. Even something as simple as a virtual destructor is sufficient.
The machinery needed to do dynamic_cast
is non-zero. So, under the "pay for what you use" principle, only those classes where it would be useful pay for them. IE: those classes which are virtual.