///////////////////////////////////////////////////////// // MT4Q3 - Copy constructor for class that aggregates // // // // Jim Fawcett, CSE687 - OOD Midterm, Spring 2013 // ///////////////////////////////////////////////////////// #include #include #include "../MTutility/MTutility.h" typedef const std::string& Stref; template void identify(Stref name) { std::cout << "\n " << typeid(T).name() << " here. My name is: " << name; } class C { public: C(Stref name) : CName_(name) {} void say() { identify(CName_); } private: std::string CName_; }; class B { public: B(Stref BName, Stref CName) : c(CName), BName_(BName) {} virtual ~B() {} virtual void say() { identify(BName_); c.say(); } private: std::string BName_; C c; }; class A { public: A(Stref name) : AName_(name) {} void say() { identify(AName_); } private: std::string AName_; }; class D : public B { public: D(Stref DName, Stref AName, Stref BName, Stref CName) : B(BName, CName), DName_(DName), pA(new A(AName)) {} D(const D& d) : B(d), DName_(d.DName_) { if(!d.pA) pA = 0; else pA = new A(*d.pA); } // The copy ctor below works for this class since all constructors initialize the pA pointer // D(const D& d) : B(d), pA(new(*d.pA)), DName_(d.DName_) {} ~D() { delete pA; } // deleting pointer with zero value does no harm virtual void say() { identify(DName_); B::say(); if(pA) pA->say(); } D& operator=(const D& d) { if(this == &d) return *this; static_cast(*this) = d; delete pA; if(!d.pA) pA = 0; else pA = new A(*d.pA); DName_ = d.DName_; } private: std::string DName_; A* pA; }; int main() { Title("MT4Q3 - Copy constructor for class that aggregates"); D d("Groucho", "Harpo", "Chico", "Gummo"); d.say(); std::cout << "\n making copy"; D dcopy = d; dcopy.say(); std::cout << "\n assigning copy to original"; d = dcopy; d.say(); std::cout << "\n\n"; return 0; }