// MT4Q2.cpp #include template class clonerBase { public: clonerBase() {} clonerBase(const clonerBase& cb) { std::cout << "\n making copy of clonerBase"; } static clonerBase* sclone() { return new T; } // returns new default instance static clonerBase* sclone(T* pT) { return new T(*pT); } // returns copy clonerBase* clone(T* pT) { return new T(*pT); } // returns copy clonerBase* clone() // returns copy of derived using base pointer { T* temp = dynamic_cast(this); if(temp) return new T(*temp); else return 0; } virtual void op()=0 { std::cout << "\n Hi from " << typeid(*this).name(); } // virtual void op()=0 { std::cout << "\n Hi from " << typeid(T).name(); } // this works too virtual ~clonerBase() {}; }; class clonerD1 : public clonerBase { public: void op() { std::cout << "\n Hi from clonerD1"; } }; class clonerD2 : public clonerBase { public: void op() { std::cout << "\n Hi from clonerD2"; } }; class clonerD3 : public clonerBase { public: void op() { clonerBase::op(); } }; void main() { // These clones simply return a new object of derived type clonerBase* pD1 = clonerBase::sclone(); pD1->op(); delete pD1; clonerBase* pD2 = clonerBase::sclone(); pD2->op(); delete pD2; // These copy generators will not accept a base pointer, // as that would require an implicit downcast which the // compiler is unwilling to do. Need dynamic_cast, // illustrated after these two clonerD2 cD2; clonerBase* pD2a = clonerBase::sclone(&cD2); pD2a->op(); clonerBase* pD2b = pD2a->clone(&cD2); pD2b->op(); // We can return copy of derived without passing a specific argument. // Type of copy is dynamic type of pointer used to invoke it, e.g. // clonerD2, below. clonerBase* pV = pD2->clone(); pV->op(); delete pD2a; // This shows that op() can be defined in base class too clonerBase* pD3 = clonerBase::sclone(); pD3->op(); delete pD3; std::cout << "\n\n"; }