////////////////////////////////////// // MT2Q2.cpp - cross casting #include /////////////////////////////////////////////////////////// // Cross casting of pointers and references // ---------------------------------------- // - code below shows that this is possible for both // pointers and references to derived objects // - The only reason you might do this is to provide // functional wrappers around a large set of data // - assume that data is so large you don't want to copy // - you need, in different contexts, different operations // supported by the same interface, e.g., a typical // polymorphic situation, but you want to work on // one shared body of data. // - note that these operations are risky - they break // type safety. class B { public: virtual ~B() {} virtual void say() { std::cout << "\n I am a B object"; } }; class D1 : public B { public: virtual void say() { std::cout << "\n I am a D1 object"; } }; class D2 : public B { public: virtual void say() { std::cout << "\n I am a D2 object"; } void unique() { std::cout << "\n function unique to D2"; } }; class foobar { public: void say() { "\n foobar here"; } void saybar() { "\n foobar here"; } }; void main() { D1* pD1 = new D1; ///////////////////////////////////////// // dynamic_cast fails because pD1 // does not point to a D2 object D2* pD2 = dynamic_cast(pD1); if(pD2) std::cout << "\n dynamic_cast succeeded"; else std::cout << "\n dynamic_cast failed"; D1& rD1 = *pD1; try { D2& refD2 = dynamic_cast(rD1); } catch(std::exception&) { std::cout << "\n dynamic_cast failed"; } //////////////////////////////////////// // applies D1::say() and D2::unique() // to D1 object pD2 = reinterpret_cast(pD1); pD2->say(); pD2->unique(); D2& refD2 = reinterpret_cast(rD1); refD2.say(); refD2.unique(); ///////////////////////////////////////// // old style casts work and have the // same behavior as reinterpret_cast pD2 = (D2*)pD1; pD2->say(); pD2->unique(); D2& refD2again = (D2&)(*pD1); refD2again.say(); refD2again.unique(); //////////////////////////////////////// // compiles and crashes beautifully // // foobar fb; // pD2 = reinterpret_cast(&fb); // pD2->say(); //////////////////////////////////////////////// // pD2->saybar(); fails to compile since not // in B interface std::cout << "\n\n"; }