Type Casting (static_cast & more)
Sometimes a value is the wrong type and you need to convert it deliberately. C++ gives you four named casts — static_cast , dynamic_cast , const_cast , and reinterpret_cast — each with a clear purpose. This lesson teaches you which to reach for, why they beat C-style (int) casts, and the truncation traps to watch for.
Learn Type Casting (static_cast & more) in our free C++ course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…
Part of the free C++ course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Think of the four casts as four different adapters . static_cast is a sensible travel adapter — it connects compatible plugs (an int into a double socket). dynamic_cast is a security guard who checks ID at the door and turns you away if you're not really who you claim to be. const_cast is a master key that removes a "do not touch" sticker — powerful but easy to misuse. reinterpret_cast is a crowbar that forces two unrelated things together by brute reinterpretation of their bits. You reach for the gentlest tool that does the job — almost always static_cast .
1. static_cast : the workhorse
This is the cast you'll use 95% of the time. It converts between related types: int ↔ double , char ↔ its numeric code, and pointers within a hierarchy. The classic use is breaking the integer-division trap by casting one operand to double .
2. Truncation vs Rounding
Casting a double to int truncates toward zero — it chops the fraction, it does not round. If you want the nearest whole number, round first with std::round (or use std::lround , which returns an integer directly).
3. dynamic_cast : safe downcasting
When you have a base-class pointer and need to know the real derived type, dynamic_cast checks at runtime. It returns nullptr for pointers (or throws std::bad_cast for references) when the object isn't the type you asked for. It requires the base class to be polymorphic — at least one virtual function.
4. const_cast : removing const (carefully)
const_cast adds or removes const . Its main legitimate use is calling an older API that forgot to mark a read-only parameter const . Never use it to actually modify an object that is genuinely const — that's undefined behavior.
5. reinterpret_cast : raw bits (last resort)
This is the most dangerous cast. It views the same bytes through a completely different type — useful for low-level work like inspecting a value's individual bytes or treating a pointer as an integer address, but non-portable and easy to misuse. Reach for it only when nothing else works.
Your turn. Cast one operand so the percentage keeps its decimals:
These lines round a price to the nearest cent-free whole number and print it. Reorder so the program prints 4 .
Why: must precede any use of round . Inside main , declare price first, then round(3.6) gives 4.0 and static_cast<int> converts that cleanly to 4 (rounding before casting avoids truncating 3.6 down to 3 ). Then print and close the function.
Predict the output before revealing each answer.
2 — casting a double to int truncates toward zero; it does not round to 3.
a — 97 is the ASCII code for lowercase 'a', so casting the int to char prints that character.
2.5 — casting one operand to double makes the whole division floating-point.
Read points earned and possible, compute a rounded percentage with a cast, and map it to a letter grade. Match the expected output in the comments.
Practice quiz
What does static_cast<int>(3.9) evaluate to?
- 4
- 3.9
- 3
- 0
Answer: 3. Converting a double to int truncates toward zero — it drops the fraction rather than rounding, so 3.9 becomes 3.
What does static_cast<int>(-3.9) evaluate to?
- -3
- -4
- -3.9
- 3
Answer: -3. Truncation is toward zero, not toward negative infinity, so -3.9 becomes -3 (not -4).
Which cast should you reach for 95% of the time, for related numeric and char conversions?
- reinterpret_cast
- const_cast
- dynamic_cast
- static_cast
Answer: static_cast. static_cast handles well-defined, related conversions and is checked at compile time. It is the everyday workhorse cast.
Which cast is used for safe downcasting in a class hierarchy, checked at runtime?
- static_cast
- dynamic_cast
- const_cast
- reinterpret_cast
Answer: dynamic_cast. dynamic_cast checks the real type at runtime, returning nullptr for pointers (or throwing std::bad_cast for references) on failure.
What does dynamic_cast require of the base class to work?
- At least one virtual function (polymorphic)
- A copy constructor
- A const destructor
- Template parameters
Answer: At least one virtual function (polymorphic). dynamic_cast needs the base class to be polymorphic — at least one virtual function (commonly a virtual destructor).
What does static_cast<double>(7) / 2 evaluate to?
- 3
- 3.0
- 3.5
- 4
Answer: 3.5. Casting one operand to double makes the division floating-point: 7.0 / 2 = 3.5.
What does static_cast<double>(7 / 2) evaluate to?
- 3.5
- 3.0
- 4.0
- 2
Answer: 3.0. The integer division 7 / 2 happens first and truncates to 3; casting that to double gives 3.0. Cast an operand, not the result.
What does static_cast<char>(97) print?
- 97
- 9
- A
- a
Answer: a. 97 is the ASCII code for lowercase 'a', so casting the int to char yields that character.
What is the main legitimate use of const_cast?
- Speeding up loops
- Calling a legacy API that forgot to mark a parameter const
- Converting double to int
- Downcasting pointers
Answer: Calling a legacy API that forgot to mark a parameter const. const_cast strips const to satisfy older non-const APIs. Actually modifying a genuinely const object through it is undefined behavior.
Why prefer named C++ casts over a C-style cast like (int)x?
- They are shorter to type
- They run faster at runtime
- They make intent explicit and let the compiler reject nonsense
- They are required by the standard
Answer: They make intent explicit and let the compiler reject nonsense. A C-style cast silently tries const_cast, static_cast, even reinterpret_cast. Named casts state intent, are searchable, and reject invalid conversions.