/////////////////////////////////////////////////////////////// // MT1Q2.cpp - Factory with Key // // // // Jim Fawcett, CSE687 - OOD Midterm, Spring 2013 // /////////////////////////////////////////////////////////////// /* * For simplicity this code does no more than the question required. * See MT1Q2b for a more realistic implemention. */ #include #include #include #include "../MTutility/MTutility.h" struct ICreatable { virtual ICreatable* create()=0; virtual ~ICreatable() {} void say() { std::cout << "\n " << typeid(*this).name() << " here"; } }; class Factory { public: void registerPrototype(const std::string& key, ICreatable* prototype); ICreatable* createInstance(const std::string& key); ~Factory(); private: std::unordered_map map; }; void Factory::registerPrototype(const std::string& key, ICreatable* ptr) { map[key] = ptr; } ICreatable* Factory::createInstance(const std::string& key) { return map[key]->create(); } Factory::~Factory() { for(auto keyValuePair : map) delete keyValuePair.second; } class testBase : public ICreatable { public: testBase() { std::cout << "\n constructing testBase"; } testBase* create() { return new testBase(*this); } void testBaseSay() { std::cout << "\n testBase non-virtual method call"; } virtual void testVirtualSay() { std::cout << "\n testBase virtual method call"; } virtual ~testBase() { std::cout << "\n destroying testBase"; } }; class testDerived : public testBase { public: testDerived() { std::cout << "\n constructing testDerived"; } testDerived* create() { return new testDerived(*this); } void testDerivedSay() { std::cout << "\n testDerived non-virtual method call"; } virtual void testVirtualSay() { std::cout << "\n testDerived virtual method call"; } virtual ~testDerived() { std::cout << "\n destroying testDerived"; } }; class other : public ICreatable { public: other() { std::cout << "\n constructing other"; } other* create() { return new other(*this); } void otherSay() { std::cout << "\n other non-virtual method call"; } ~other() { std::cout << "\n destroying other"; } }; int main() { Title("MT1Q2 - Factory with key"); Factory factory; factory.registerPrototype("testBase", new testBase()); factory.registerPrototype("testDerived", new testDerived()); factory.registerPrototype("other", new other()); testBase* pTestBase = dynamic_cast(factory.createInstance("testBase")); pTestBase->say(); pTestBase->testVirtualSay(); pTestBase->testBaseSay(); delete pTestBase; // demonstrate that created objects can be used polymorphically testBase* pTestDerived = dynamic_cast(factory.createInstance("testDerived")); pTestDerived->say(); pTestDerived->testVirtualSay(); // access extended interface dynamic_cast(pTestDerived)->testDerivedSay(); delete pTestDerived; // demonstrate that objects can be on diffe other* pOther = dynamic_cast(factory.createInstance("other")); pOther->say(); pOther->otherSay(); delete pOther; std::cout << "\n\n"; }