// MT2Q3.cpp #include class B { public: B() { std::cout << "\n default construction of B"; } B(const B& b) { std::cout << "\n copy construction of B"; } B& operator=(const B& b) { std::cout << "\n assigning B"; if(this == &b) return *this; // if there were data members, assign them here return *this; } virtual ~B() { std::cout << "\n destroying B"; } void say() const { std::cout << "\n B here"; } }; class C { public: C(double val=0) : val_(val) { std::cout << "\n default construction of C"; } C(const C& c) : val_(c.val_) { std::cout << "\n copy construction of C"; } C& operator=(const C& c) { std::cout << "\n assigning C"; if(this == &c) return *this; val_ = c.val_; return *this; } ~C() { std::cout << "\n destroying C"; } void say() const { std::cout << "\n C here"; std::cout << "\n my value is " << value(); } double& value() { return val_; } double value() const { return val_; } private: double val_; }; class U { public: U() { std::cout << "\n default construction of U"; } U(const U& u) { std::cout << "\n copy construction of U"; } ~U() { std::cout << "\n destroying U"; } void say() const { std::cout << "\n U here"; } }; class D : public B { public: D() { std::cout << "\n default construction of D"; } D(const D& d) : B(d), c(d.c) { std::cout << "\n copy construction of D"; }; D& operator=(const D& d) { std::cout << "\n assigning D"; if(this == &d) return *this; static_cast(*this) = d; c = d.c; return *this; } ~D() { std::cout << "\n destroying D"; } void say(const U& u) const { std::cout << "\n D here"; c.say(); u.say(); } double& value() { return c.value(); } private: C c; }; class modD : public B { public: modD() : pC(0) { std::cout << "\n default construction of modD"; } modD(const modD& md) : B(md) { std::cout << "\n copy construction of modD"; if(md.pC != 0) pC = new C(*md.pC); else pC = 0; }; void createC(double val) { pC = new C(val); } modD& operator=(const modD& md) { std::cout << "\n assigning modD"; if(&md == this) return *this; static_cast(*this) = md; if(md.pC != 0) pC = new C(*md.pC); else pC = 0; return *this; } ~modD() { std::cout << "\n destroying modD"; if(pC) delete pC; } void say(const U& u) const { std::cout << "\n modD here"; if(pC) pC->say(); u.say(); } double& value() { if(pC == 0) pC = new C; return pC->value(); } private: C* pC; }; void main() { U u; D d1; // d1.say(u); D d2 = d1; // d2.say(u); // d2.value() = 3.1415927; // d2.say(u); modD md1; // md1.say(u); modD md2 = md1; // md2.say(u); md1.createC(3.1415927); modD md3 = md1; // md2.say(u); }