🎭Casting

Here are 4 types of casting in cpp:

  1. Static Cast (static_cast<new_type>(expression))

  • Purpose: Used for converting between related types.

  • Safety: Relatively safe, as it performs compile-time type checking.

  • Use cases:

    • Implicit conversions (e.g., int to float)

    • Explicit type conversions between related classes (up and down a class hierarchy)

    • Conversion between pointer types in a class hierarchy

  • Checked at: Compile-time

  • Example:

    double d = 3.14;
    int i = static_cast<int>(d);  // Converts double to int
  1. Dynamic Cast (dynamic_cast<new_type>(expression))

  • Purpose: Used for safe downcasting in inheritance hierarchies.

  • Safety: Very safe, as it performs runtime type checking.

  • Use cases:

    • Converting pointers/references within an inheritance hierarchy

    • Determining runtime type information

  • Checked at: Run-time

  • Requires: At least one virtual function in the base class

  • Example:

    class Base { virtual void foo() {} };
    class Derived : public Base { void bar() {} };
    
    Base* basePtr = new Derived;
    Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);
    if (derivedPtr) {
        // Safe to use derivedPtr
    }
  1. Const Cast (const_cast<new_type>(expression))

  • Purpose: To add or remove const/volatile qualifiers.

  • Safety: Can be unsafe if misused, as it allows modification of const objects.

  • Use cases:

    • Removing const-ness from objects that were originally non-const

    • Working with APIs that don't use const correctly

  • Checked at: Compile-time

  • Example:

    const int* constPtr = new int(10);
    int* mutablePtr = const_cast<int*>(constPtr);
    *mutablePtr = 20;  // Modifies the originally const value
  1. Reinterpret Cast (reinterpret_cast<new_type>(expression))

  • Purpose: For low-level reinterpretation of bit patterns.

  • Safety: Least safe, as it performs no checking and can easily lead to undefined behavior.

  • Use cases:

    • Converting between unrelated pointer types

    • Converting between pointer and integer types

    • Bit manipulation

  • Checked at: Compile-time (only for syntax, not for safety)

  • Example:

    int i = 42;
    char* charPtr = reinterpret_cast<char*>(&i);

Key Differences:

  1. Safety:

    • dynamic_cast is the safest, with runtime checks.

    • static_cast is next, with compile-time checks.

    • const_cast is potentially unsafe if misused.

    • reinterpret_cast is the least safe, with no real checks.

  2. Purpose:

    • static_cast is for general-purpose conversions.

    • dynamic_cast is specifically for class hierarchies.

    • const_cast is solely for const/volatile manipulation.

    • reinterpret_cast is for low-level reinterpretation.

  3. Runtime Overhead:

    • dynamic_cast has the most overhead due to runtime type checking.

    • The others have minimal to no runtime overhead.

  4. Compile-time vs. Runtime:

    • Only dynamic_cast performs checks at runtime.

    • The others are resolved at compile-time.

  5. Type Relationship:

    • static_cast and dynamic_cast work with related types.

    • const_cast works only on cv-qualifiers.

    • reinterpret_cast can work with completely unrelated types.

In general, it's best to use the most restrictive cast that accomplishes the task. static_cast should be your go-to for most situations, dynamic_cast when working with polymorphic types, const_cast sparingly when absolutely necessary, and reinterpret_cast only in very specific low-level scenarios.

Last updated