Thing is, there are several broadly different categories of casts, with varying intent, and it is desirable to be able to explicitly specify that intent, so that you accidentally don't do the wrong thing. For example, you might be casting a const int*
to const char*
to operate on raw bytes, and unintentionally also drop the const
. Consequently, in C++, changing the pointer from one unrelated type to another is done with reinterpret_cast
, while casting away const can only be done with const_cast
. If you try const void* p; reinterpret_cast<char*>(p)
, you'll get an error.
dynamic_cast
is needed to reliably downcast things (with a runtime check), and also for cross-casts (i.e. given a pointer of type Base1*
to an object of actual type Derived
which inherits from both Base1*
and Base2*
, to be able to cast directly to Base2*
; and the same for references - this is particularly useful for "interfaces").
static_cast
is the rest of it - value conversions (int<->float etc), upcasting of object pointers/references, and unchecked downcasting. It is also the one used most often, though some style guides call for use of dynamic_cast
on all object pointer/reference casts inasmuch as possible.
In general, the rationale seems to be: two most dangerous operations (casting to pointer-to-unrelated-type, and casting away constness) are provided with their own dedicated cast operators, to prevent any possibility of them occuring accidentally. Following that, a new operator is provided for cases where the cast requires runtime lookup. Finally, yet another new operator is provided to cover any remaining ground. The old, C-style "universal" casting operator is effectively deprecated.
Now as to why Obj-C doesn't "need" them. Arguably, it could actually use the difference between const_cast
, reinterpret_cast
and static_cast
- but those were, apparently, seen as not adding enough value to extend the core C language. It doesn't need dynamic_cast
, because it doesn't have multiple inheritance (protocols are somewhat different), and type checks are done via isa
method instead.