///////////////////////////////////////////////////// // MT1Q2_2Q1_3Q2_4Q4.cpp - copy, assign, destroy // // // // Jim Fawcett, CSE687 - Midterm, Spring 2010 // ///////////////////////////////////////////////////// // MT1Q2.cpp and MT2Q1.cpp #include #include class Shared { public: static void show() { std::cout << "\n " << shared_ << "\n\n"; } static std::string& value() { return shared_; } template static std::string say(const std::string& msg); private: static std::string shared_; }; std::string Shared::shared_ = ""; template std::string Shared::say(const std::string& msg) { return std::string("\n ") + typeid(T).name() + std::string(" ") + msg; } class U // compiler defined copy, assign, and destroy are correct for U { // so we should not implement except for display as done here public: U(); U(const U& u); ~U(); U& operator=(const U& u); std::string say(); }; U::U() { Shared::value() += Shared::say("void construction"); } U::U(const U& u) { Shared::say("copy"); } U::~U() { Shared::value() += Shared::say("destruction"); } U& U::operator =(const U& u) { if(!(this == &u)) { Shared::value() += Shared::say("assignment"); } return *this; } std::string U::say(){ return typeid(*this).name(); } class A // Needs copy, can't assign, compiler defined destroy works. { // Should not define a void constructor since A needs its u_ public: A(U& u); A(const A& a); // can copy construct references like u_ ~A(); std::string say(); private: A& operator=(const A&); U& u_; // can't reset reference so can't assign }; A::A(U& u) : u_(u) { Shared::value() += Shared::say("promotion"); }; A::A(const A& a) : u_(a.u_) { Shared::value() += Shared::say("copy"); } A::~A() { Shared::value() += Shared::say("destruction"); } std::string A::say() { return typeid(*this).name() + std::string(" ") + u_.say(); } class B // Needs copy, assignment, destructor due to pointer memeber. { // Should not define void constructor since B needs its A. public: B(const A& a); B(const B& b); virtual ~B(); B& operator=(const B&); virtual std::string say(); private: A* pA; }; B::B(const A &a) : pA(new A(a)) { Shared::value() += Shared::say("promotion"); } B::B(const B& b) : pA(new A(*(b.pA))) { Shared::value() += Shared::say("copy"); } B::~B() { Shared::value() += Shared::say("destruction"); delete pA; } B& B::operator =(const B& b) { if(this != &b) { Shared::value() += Shared::say("assignment"); delete pA; pA = new A(*b.pA); } return *this; } std::string B::say() { return typeid(*this).name() + std::string(" ") + pA->say(); } class D : public B // Compiler define copy, assignment, destructor ok. { // Should not implement except for display as done here. public: // Should not define void constructor since D needs its a. D(const A& a); D(const D& d); ~D(); D& operator=(const D&); std::string say(); private: }; D::D(const A& a) : B(a) { Shared::value() += Shared::say("promotion"); } D::D(const D& d) : B(d) { Shared::value() += Shared::say("copy"); } D::~D() { Shared::value() += Shared::say("destruction"); } D& D::operator =(const D& d) { if(!(this == &d)) { Shared::value() += Shared::say("assignment"); (B&)(*this) = d; } return *this; } std::string D::say() { return typeid(*this).name() + std::string(" ") + B::say(); } void main() { std::cout << "\n MT1Q2_2Q1_3Q2_4Q4.cpp - copy, assign, destroy"; std::cout << "\n ==============================================="; { Shared::value() = "\n Showing construction of composite objects"; U u; A a(u); D d1(a); // Uncomment portions of this to see operations required in your exam. //Shared::value() += "\n Showing copy and assignment of composite objects"; //D d2 = d1; //d1 = d2; //Shared::value() += "\n"; //std::cout << "\n Showing each Type's construction"; //U u3; //std::cout << "\n " << u3.say(); //A a3(u3); //std::cout << "\n " << a3.say(); //B b3(a3); //std::cout << "\n " << b3.say(); //D d3(a3); //std::cout << "\n " << d3.say(); } Shared::show(); }