C++ provides four different types of casting operators:
- static_cast
- reinterpret_cast
- dynamic_cast
- const_cast
Each has its specific use case and level of safety.
Unlike C-style casts, C++ casts are:
- More visible in code
- More specific in purpose
- Easier to search for
- Safer to use
- Most common type conversion
- Performs compile-time type checking
- Used for converting between related types
double d = 3.14;
int i = static_cast<int>(d); // Convert double to int
- Numeric conversions
- Pointer conversions up inheritance hierarchies
- void* to typed pointer conversions
- Base to derived class pointers (when you're sure it's safe)
- No runtime type checking
- Can't remove const
- Can't handle unrelated types
- Low-level reinterpreting of bit patterns
- Used for pointer/reference conversions between unrelated types
int* p = new int(42);
long addr = reinterpret_cast<long>(p); // Convert pointer to integer
- Converting between pointer types
- Converting pointer to integral type
- Converting integral type to pointer
- Very dangerous if misused
- Implementation-dependent
- Should be used rarely
- Safe downcasting in inheritance hierarchies
- Runtime type checking
- Works with polymorphic classes
Base* base = new Derived();
Derived* derived = dynamic_cast<Derived*>(base);
- Runtime Type Information (RTTI)
- Returns nullptr for invalid pointer casts
- Throws std::bad_cast for invalid reference casts
- Base class must be polymorphic (have virtual functions)
- RTTI must be enabled
- Remove or add const qualifier
- Should be used very rarely
- Often indicates design problems
const int constant = 21;
const_cast<int&>(constant) = 42; // Remove const (dangerous!)
- Modifying a const object is undefined behavior
- Should only be used when dealing with poorly designed APIs
- Convert between scalar types
- Handle edge cases and special values
- Use appropriate type casting
static void convert(const std::string& literal);
Key Concepts:
- Type detection
- Safe conversion
- Special value handling
- Output formatting
- Convert pointer to integer and back
- Use reinterpret_cast for pointer conversions
uintptr_t serialize(Data* ptr);
Data* deserialize(uintptr_t raw);
Key Concepts:
- Pointer serialization
- Data integrity
- Memory safety
- Type safety
- Identify real type of objects
- Use dynamic_cast for type checking
Base* generate(void);
void identify(Base* p);
void identify(Base& p);
Key Concepts:
- Polymorphic classes
- Runtime type identification
- Type safety with inheritance
- Dynamic casting
-
static_cast:
- General-purpose conversions
- Numeric type conversions
- When type safety is known at compile time
-
reinterpret_cast:
- Low-level bit manipulation
- System-level programming
- When you need to break type safety
-
dynamic_cast:
- Safe downcasting
- When you need runtime type checking
- Working with polymorphic types
-
const_cast:
- Last resort
- When working with legacy APIs
- When const-correctness is broken