Object-Oriented Programming

CSCI-UA.0470-001

NYU, Undergraduate Division, Computer Science Course - Fall 2013

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!
    • example in cast.cc
    • 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)
    • example in cast.cc
    • Circle* c1 = static_cast<Rectangle*>(s)

Treat something as const

  • Safe.
  • But object can still be modified by accessing original pointer
    • example in cast.cc

    • 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
    • example in cast.cc

    • Circle* c2 =const_cast<Circle*>(c1);

Reinterpret Cast

  • Reinterpret bits completely differently
  • Can cast into unrelated classes, which is insanely bad
    • examples in cast.cc
    • 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

  • Guaranteed to be safe
    • example in cast.cc
    • 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.