/////////////////////////////////////////////////// // MT4Q2.cpp - Non-virtual Base class clone() // // // // Jim Fawcett, CSE687 - Midterm, Spring 2010 // /////////////////////////////////////////////////// #include #include class IBase { public: virtual std::string id()=0; }; template class Base : public IBase { public: IBase* clone() { // this cast is necessary since compiler doesn't // know now that D derives from Base (see below). D* pD = dynamic_cast(this); if(pD == 0) throw std::exception("D must derive from Base"); return new D(*pD); } virtual std::string id() { return std::string("\n my id is: ") + typeid(Base).name(); } virtual ~Base() {} }; class Derived1 : public Base { public: Derived1(const std::string& msg) : msg_(msg) {} // will use inherited clone() virtual std::string id() { std::string temp = "\n my id is: "; temp += typeid(*this).name(); temp += std::string("\n my message is: ") + msg_; temp += std::string("\n my base class says: ") + Base::id(); return temp; } private: std::string msg_; }; class Derived2 : public Base { public: Derived2(const std::string& msg) : msg_(msg) {} // will use inherited clone virtual std::string id() { std::string temp = "\n my id is: "; temp += typeid(*this).name(); temp += std::string("\n my message is: ") + msg_; temp += std::string("\n my base class says: ") + Base::id(); return temp; } private: std::string msg_; }; void main() { std::cout << "\n MT4Q2 - Non-Virtual Base Clone()"; std::cout << "\n ==================================\n"; Base b; std::cout << b.id().c_str() << std::endl;; Derived1 d1("Hello CSE687"); IBase* pB = d1.clone(); // note that message state is copied by clone() // to copy on heap std::cout << pB->id().c_str() << std::endl;; Derived2 d2("Hello Object Oriented Design"); pB = d2.clone(); // yup, still copied! std::cout << pB->id().c_str(); std::cout << "\n\n"; }