There are usually three different ways to write the same cast.
1 | (T)expression |
There is no difference in meaning between these forms; it’s purely a matter of where you put the parentheses. I call these two forms old-style casts.
C++ also offers four new cast forms (often called new-style or C++-style casts):
1 | const_cast<T>(expression) |
Each serves a distinct purpose:
const_cast
is typically used to cast away the constness of objects. It is the only C++-style cast that can do this.dynamic_cast
is primarily used to perform “safe downcasting,” i.e., to determine whether an object is of a particular type in an inheritance hierarchy. It is the only cast that cannot be performed using the old-style syntax. It is also the only cast that may have a significant runtime cost.reinterpret_cast
is intended for low-level casts that yield implementation-dependent (i.e., unportable) results, e.g., casting a pointer to an int. Such casts should be rare outside low-level code.static_cast
can be used to force implicit conversions (e.g., non-const object to const object, int to double, etc.). It can also be used to perform the reverse of many such conversions (e.g., void* pointers to typed pointers, pointer-to-base to pointer-to-derived), though it cannot cast from const to non-const objects. (Onlyconst_cast
can do that.)
The general rule is to avoid using cast as much as possible. const_cast
is almost aways a bad idea because it breaks const
semantics. dynamic_cast
is a indication of bad inheritance design or mis-use of inheritance. For example, following code should never happen
1 | class Window { ... }; |
static_cast
is sometimes ok to use, but it also has caveat since it creates a new temporary object. Considering following code
1 | class Window { |
You would think static_cast<Window>(*this).onResize();
is equivalent to Window::onResize();
, but it’s not. static_cast<Window>(*this)
will create a new temporary object and onResize()
will be invoked on that temporary object instead of this
object.
Things to remember:
- Avoid casts whenever practical, especially dynamic_casts in performance-sensitive code. If a design requires casting, try to develop a cast-free alternative.
- When casting is necessary, try to hide it inside a function. Clients can then call the function instead of putting casts in their own code.
- Prefer C++-style casts to old-style casts. They are easier to see, and they are more specific about what they do.