OOP Class Notes for 11/21/13
C++ Casting
- C casting is allowed in C++, but it is deprecated.
- C++ has its own ways of casting
Implicit Cast
- Always safe
- But problematic since nonvirtual methods will not be dynamically
dispatched, specificially nonvirtual destructors!
Shape* s = new Circle();
Static Cast
- Asserts the cast is correct
- Unsafe, but compiler still checks if the classes are related (i.e., the cast is either up or down the inheritance hierarchy)
Circle* c1 = static_cast<Rectangle*>(s)
Treat something as const
- Safe.
- But object can still be modified by accessing original pointer
const Circle* c2 = c1;
Const Cast
- Casting away const-ness, Dangerous. (Also works to treat
something as
const
). The compiler checks that the source and targe types are the same modulo const
Circle* c2 =const_cast<Circle*>(c1);
Reinterpret Cast
- Reinterpret bits completely differently
- Can cast into unrelated classes, which is insanely bad
intptr_t i = reinterpret_cast<intptr_t>(c3);
Window* w1 = reinterpret_cast<Window*>(c3);
the above will compile but will treat a Circle as a Window object. Super bad.
Dynamic Cast
Circle* c4 = dynamic_cast<Circle*>(s);
Can't compile since Shape doesn't have a virtual method
No virtual method → no vtable → no type information for the compiler
Rectangle* r2 = dynamic_cast<Rectangle*>(s);
When the cast fails, no exception occurs, and null pointer is returned.
This is because exceptions are costly and the C++ standard committee made them optional.
Rectangle& r3 = dynamic_cast<Rectangle&>(*s);
References cannot be null, so the code does result in an exception.
Summary
static_cast
, const_cast
, and reinterpret_cast
have no runtime overhead.
- However, they all assume the cast is valid, and you as the programmer know better than the compiler. None of them is safe from human error.
dynamic_cast
requires some overhead (similar to down
casts in Java).
- It's safe, but you will need to check if the casting succeeded for pointers.