#include #include class B { public: void say(const std::string& msg) const { std::cout << "\n " << msg; } B() { say("B default ctor"); } B(const B& b) { say("B copy ctor"); } virtual ~B() {} B& operator=(const B& b) { say("B assignment"); if(&b == this) return *this; // no state to assign return *this; } }; class D : public B { public: D() : B() { say("D default ctor"); } D(const D& d) : B(d) { say("D copy ctor"); } D& operator=(const D& d) { say("D assignment"); if(&d == this) return *this; B::operator=(d); i = d.i; return *this; } private: int i; }; B* f(const B& obj) { obj.say("f(const B& obj)"); // The next statement will never compile. // You can't promote base to derived. // return new D(obj); // this works: const D* pD = dynamic_cast(&obj); if(pD) return new D(*pD); else throw std::exception("can't promote base to derived"); } void main() { D d; B b; try { // attempting to assign to d D* pD = dynamic_cast(f(d)); if(pD) d = *pD; // attempting to assign to b b = *f(d); } catch(std::exception& ex) { std::cout << "\n " << ex.what(); } std::cout << "\n\n"; }