Wednesday, June 09, 2010

C++ casts Demystified

Hope the following code sample clarifies the differences between the various C++ casts. const_cast is left as a trivial case.


class V {public: virtual ~V(){}}; //Virtual Base Class

class G: virtual public V{}; //Common ancestor for base classes
class B1: public G{};

class B2{}; //Non-polymorphic class
class B3: public G{};

class D: public B1, public B2, public B3 {};

class I{ public: virtual ~I(){}}; //Independent, unrelated Class

int main(int argc, char* argv[])

{
D d;
D* pdd=&d;
B1* pb1d=&d; //No casts needed

B2* pb2d=&d;
B3* pb3d=&d;
V* pvd=&d;

//G* pgd=&d; //Compile-error, ambiguous

// I* pi1d=&d; //Cast needed. Compile error.
I* pi1d=(I*)&d; //No compile error, but semantically wrong. Address gets assigned.

//I* pi1d=static_cast<I*>(&d); //Compile error

//Upcasting
B1* pb1= dynamic_cast<B1*>(pdd); // = pb1d

B2* pb2= dynamic_cast<B2*>(pdd); // = pb2d

B3* pb3= dynamic_cast<B3*>(pdd); // = pb3d

G* g1 = dynamic_cast<G*>(pdd); //No compile-error, but null because ambiguous

G* g2 = reinterpret_cast<G*>(pdd); //No compile-error, nothing

//G* g3 = static_cast<G*>(pdd); //Compile-error, but null because ambiguous

//Downcasting
D* pdd1 = dynamic_cast<D*>(pb1d); //downcast, B1 must be polymorphic

//D* pdd = dynamic_cast<D*>(pb2d); //downcast, B2 not polymorphic. Compile error.
G* g3= dynamic_cast<G*>(pvd); //ambiguous downcast, = null, compiles in C++ not in Comeau

// G* g4= static_cast<G*>(pvd); //ambiguous downcast, = null

//Crosscasting
I* pi= dynamic_cast<I*>(pdd); //pi will be null

I* pi2= reinterpret_cast<I*>(pdd); //pi2 will be equal to pdd

//I& ri= dynamic_cast<I&>(*pd); //throws an exception

B3* pb31= dynamic_cast<B3*> (pb1d);



return 0;
}