Intermediate⏱️ 9 min📘 Topic 7 of 32

🎭 Type Casting in C++ — static_cast, dynamic_cast, const_cast & reinterpret_cast

Master C++ type casting — implicit vs explicit conversions, C-style casts vs the four modern cast operators (static_cast, dynamic_cast, const_cast, reinterpret_cast).

Type casting converts a value from one type to another. C++ supports both implicit (automatic) and explicit (you ask for it) conversions.

🔄 Implicit conversions

int x = 5;
double d = x;        // implicit int -> double, lossless
int y = 3.7;          // implicit double -> int, truncates to 3

🎭 Four explicit cast operators (modern C++)

  • static_cast<T> — safe, related-type conversions (numeric, base↔derived). Most common.
  • dynamic_cast<T> — safe downcast in inheritance (returns nullptr if not valid). Requires virtual functions.
  • const_cast<T> — add or remove const. Rarely needed.
  • reinterpret_cast<T> — raw bit reinterpretation. Dangerous, use sparingly.

📜 The C-style cast — avoid

int x = (int) 3.7;  // works but tells the reader nothing about intent

Modern code uses the four named casts because they signal exactly what kind of conversion you mean.

💡 Quick decision guide

GoalUse
int ↔ doublestatic_cast
Base* → Derived* safelydynamic_cast
Drop constconst_cast
Pointer ↔ uintptr_treinterpret_cast

💻 Code Examples

static_cast for numeric conversion

int a = 5, b = 2;
double result = static_cast<double>(a) / b;
std::cout << result;
Output:
2.5

dynamic_cast — safe downcast

class Animal { public: virtual ~Animal() = default; };
class Dog : public Animal { public: void bark() {} };

Animal* a = new Dog();
Dog* d = dynamic_cast<Dog*>(a);
if (d) d->bark();   // safe
else    std::cout << "not a Dog";
Output:
Returns nullptr if the actual type isn't Dog.

const_cast — rare, careful

void legacyApi(char* msg);
const char* s = "hello";
legacyApi(const_cast<char*>(s));   // OK only if legacyApi doesn't actually modify
Output:
Use only to interface with legacy/C APIs.

⚠️ Common Mistakes

  • Using C-style casts everywhere — hides intent and bypasses type safety.
  • Using `reinterpret_cast` to 'just make it compile' — usually a sign something is wrong.
  • Calling `dynamic_cast` on a class without virtual functions — won't compile (no RTTI info).
  • Modifying a value through `const_cast` when the original was actually const — undefined behavior.

🎯 Interview Questions

Real questions asked at top product and service-based companies.

Q1.What's the difference between implicit and explicit type conversion?Beginner
Implicit: compiler does it automatically (int → double on assignment). Explicit: you request it via a cast. Implicit is convenient but can silently lose data (double → int truncates).
Q2.What are the four C++ cast operators?Intermediate
static_cast (safe related-type conversions), dynamic_cast (runtime-checked downcasts in inheritance), const_cast (add/remove const), reinterpret_cast (raw bit reinterpretation). Each signals different intent.
Q3.When does dynamic_cast return nullptr?Intermediate
When the runtime type of the source pointer/reference is NOT the requested derived type. For references, it throws std::bad_cast instead. Requires the polymorphic base to have at least one virtual function.
Q4.Why is reinterpret_cast considered dangerous?Intermediate
It tells the compiler 'trust me' — converts bit patterns between unrelated types without checks. Wrong use = undefined behavior, crashes, portability issues. Reserved for low-level interop (hardware registers, serialization).
Q5.What's the difference between (int)x, int(x) and static_cast<int>(x)?Advanced
All three convert x to int. (int)x and int(x) are C-style — the compiler tries every legal conversion (including const_cast and reinterpret_cast) which can hide bugs. static_cast is restricted to safe related conversions. Prefer static_cast for clarity.

🧠 Quick Summary

  • C++ has implicit conversions and four named explicit casts.
  • static_cast: safe related-type conversion.
  • dynamic_cast: runtime-checked downcast in inheritance.
  • const_cast: add/remove const (rare).
  • reinterpret_cast: raw bit pattern (dangerous).
  • Prefer named casts over C-style — they signal intent.