C++ Study Note(2): Cast the light to the darkness

The old-school C casting is reckless without type checking, to make it worse, the casting is easily overlooked by the maintainers. C++ introduces four cast keywords to rescue: const_cast, static_cast, dynamic_cast, and reinterpret_cast.

The keyword const is a contract between the library developers and users. Dropping the constdecorator may incur unexpected behavior, for example: ```c++ class Foo { public: Foo() : dd(0) {} // int& bar() { cout << “non-const” << dd << endl; return dd; } const int& bar() const { cout << “const” << dd << endl; return dd; } private: int dd; };

… … Foo foo; int & x = const_cast(foo.bar()); x = 3; ```

C++ impose the developers to use const_cast to highlight the action, “Warning, warning, the const decoration is dropped…”, the same reason lies in the booltype.

If you are quite confident the type downcasting, static_castis the right option for you. The compiler would adjust the offset and return a derived class pointer for you in the compile time, aka free overhead. If you could not guarantee the heritage, use dynamic_cast, the runtime would try to down cast the pointer/reference and return a valid pointer/reference if everything is OK, otherwise, a null pointer is returned for pointer down-casting, or a bad_cast exception is raised for the reference casting.

*Update: Boost’s developers dislike the inconsistence, a new cast template function**, polymorph_cast is introduced for the downcasting and crosscasting: c++ template inline Target polymorphic\_cast(Source* x BOOST\_EXPLICIT\_DEFAULT\_TARGET) { Target tmp = dynamic\_cast(x); if ( tmp == 0 ) throw std::bad\_cast(); return tmp; }

It helps the careless developers to test the validity of the returned pointer, throw an exception if necessary.

If you would like both the type safety from dynamic_cast, and also the performance of static_cast, Boost has another neat cast function, polymorphic_downcastfor you such a greedy jerk.

c++ template inline Target polymorphic_downcast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET) { BOOST_ASSERT( dynamic_cast(x) == x ); // detect logic error return static_cast(x); }

This cast only works on downcast the pointer, you can tell from the name; it does dynamic_castin the debug version and static_castin the release version.

Last and the least, reinterpret_cast, the compiler would just simply pretend the object has a new type without any validation check, offset adjustment; furthermore, it is NOT portable. Use it in caution and make sure you know clearly what you are doing.