Casting
In C++, a cast is a mechanism to explicitly convert a value from one data type to another.
Implicit Cast (Automatic)
it occurs automatically when assigning a value of one type to another compatible type. This is done by the compiler without any explicit syntax.
int x = 10;
double y = x; // implicit cast from int to double
However, implicit conversions can sometimes lead to loss of precision or unintended behavior, so C++ provides explicit casts for more control.
Explicit Casting
This is the traditional way to cast in C (and C++), but it’s not type-safe and can perform any kind of cast (e.g., static, reinterpret, or const cast) without much clarity about what kind of conversion is happening.
int x = 10;
double y = (double) x; // C-style cast from int to double
C++ Style Casts
C++ introduced four specific types of casts to provide more clarity, safety, and control over type conversions.
- static_cast
- dynamic_cast
- const_cast
- reinterpret_cast
static_cast
When you need to cast between compatible types or up/down a class hierarchy in a way that’s checked at compile time.
-
Casting numeric types (e.g.,
int
todouble
). - Casting pointers within an inheritance hierarchy.
-
Not safe for: Downcasting from a base class to a derived class (if it’s the wrong type, it could lead to undefined behavior).
double d = 3.14; int x = static_cast< int>(d); // convert double to int
#### dynamic_cast
Used for safely casting pointers or references within a class hierarchy, particularly when performing **downcasting** (from base class to derived class).It’s mostly used with polymorphic types (i.e., classes with virtual functions).
**Fails**: Returns
nullptr
if the cast fails for pointers, or throws astd::bad_cast
exception for references.class Base { virtual void func() {} }; class Derived : public Base { }; Base* basePtr = new Derived(); // safe downcast Derived* derivedPtr = dynamic_cast< Derived*>(basePtr);
const_cast
To Adds or Removes the
const
qualifier from a variable.
Usage: When you need to change the const-ness of an object, typically to call a function that is notconst
but needs to be called on aconst
object (used with caution).
Undefined Behavior: If you modify a value that was originally declared asconst
after usingconst_cast
, it can lead to undefined behavior.const int x = 10; // cast away const int& y = const_cast
(x); reinterpret_cast
Used for low-level, potentially unsafe conversions between unrelated types (e.g., converting a pointer of one type to a pointer of another, or an integer to a pointer).
Safe for: Changing the way the compiler interprets the bits of a value. Often used in systems programming.
Not Safe for: Changing object types unless you fully understand the memory layout.
int* ptr = new int(5); // reinterpret int pointer as char pointer char* bytePtr = reinterpret_cast< char*>(ptr);
Cast Type Purpose Usage Example static_cast
Compile-time cast between compatible types int x = static_cast<int>(3.14);
dynamic_cast
Safe cast for class hierarchy (downcasting, runtime check) Derived* d = dynamic_cast<Derived*>(basePtr);
const_cast
Add/remove const
qualifierint* p = const_cast<int*>(constPtr);
reinterpret_cast
Low-level cast, reinterpreting bits of data int* p = reinterpret_cast<int*>(somePtr);
Prefer C++-style casts (
static_cast
,dynamic_cast
, etc.) over C-style casts for clarity and safety.
Usestatic_cast
for common type conversions (numeric types, pointer conversions within a hierarchy).
Usedynamic_cast
for runtime-checked casts in polymorphic class hierarchies.
Useconst_cast
sparingly and only when necessary.
Usereinterpret_cast
with extreme caution, mostly in low-level systems programming where you need to manipulate raw data or pointers.