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

Development May 23rd, 2007

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 const decorator may incur unexpected behavior, for example:

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<int&>(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 bool type.

If you are quite confident the type downcasting, static_cast is 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:

template <class Target, class Source>
    inline Target polymorphic_cast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET)
    {
        Target tmp = dynamic_cast<Target>(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_downcast for you such a greedy jerk.

template <class Target, class Source>
    inline Target polymorphic_downcast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET)
    {
        BOOST_ASSERT( dynamic_cast<Target>(x) == x );  // detect logic error
        return static_cast<Target>(x);
    }

This cast only works on downcast the pointer, you can tell from the name; it does dynamic_cast in the debug version and static_cast in 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.

C++ Study Notes (0) – Syllabus

Development, Python January 29th, 2007

Course Information: Advanced topics on C++: template, STL, boost, metaprogramming etc.

Text:

Supplementary Reading:

Objective:

  • Review C++ standards
  • Revisit the STL for iterators, function objects and algorithms
  • Overview of Boost library
  • Metaprogramming instroduction based upon Boost MPL library
  • Boost.Python library study

Schedule:

  • Read the textbooks in the Metro, on the toilet, before sleep…
  • Start coding practice in the weekend.

Project: TBD
Supported services

  • News group