The traditional way of casting in C is still possible in C++, but alternative options are available which provide much better diagnoses of usage errors and are much easier to indentify and maintain.
These new casts are :
Casts away the const-ness of objects, variables or pointers. It gives an error when the types differ more than in const and volatile modifiers.
Don't use this to cast away const-ness of objects that were originally defined as being const and on which non-const operations are being executed. Doing this, results in undefined behaviour.
You typically use this when you need to access an api that incorrectly defines a function signature. When you are 100% sure that the function you want to call doesn't perform non-const operations on the argument, you can safely cast away the const-ness of the argument that was initially defined as being const.
Makes it possible to safely downcast pointers and references to base classes. It thus returns the appropriate sub-object in the hierarchy chain. It returns 0 if this cast wasn't possible on pointers and throws the bad_cast exception if the cast wasn't possible on references. This effectively says "convert this Object into a Penguin or give me 0 if its not an Penguin,". This provides dynamic typing, you don't know what will happen until run-time.
This type of casts treats pointers and references as incomplete types. Using the reinterprete_cast yields values that are typically not guaranteed to be usable without casting back to their orginal types. It's difficult to say more about this kind of casts since their applicability is very implementation dependent.
This is very similar to the old C-style casts. Only use it when none of the above seem to fit the bill. It will only succeed if there's an implicit conversion possible either from T to the type of e, or from the type of e to T.