///////////////////////////////////////////////////////////////////////// // creatable.cpp - defines object factory and provides a test stub // // ver 1.0 // // Language: Visual C++, ver 6.0, SP 5 // // Platform: Dell Dimension 8100, Win 2000 Pro, SP 2 // // Application: CSE691/791 - SWM&A Demonstration // // Author: Jim Fawcett, CST 2-187, Syracuse Univ // // (315) 443-3948, jfawcett@twcny.rr.com // ///////////////////////////////////////////////////////////////////////// #include "creatable.h" #include ///////////////////////////////////////////////////////////////////////// // Note: // // The objFactory class has no physical dependency on any class that // // wishes to use it. You can see that by observing that all the // // factory code comes before any derived class code, so it never // // sees, nor needs, any of those definitions. When we add a new // // class to be stored, we do not need to re-compile the objFactory. // ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// // define the static instance of the class registry registryType objFactory::registry; //----< register a static member creation function >--------------------- void objFactory::reg(classID id, createFunc pFun) { registry[id] = pFun; } //----< create an instance of a creatable class >------------------------ creatable* objFactory::makeObj(classID id) { creatable *theObject = NULL; registryType::const_iterator entry = registry.find(id); if(entry != registry.end()) theObject = entry->second(); return theObject; } // #ifdef TEST_CREATABLE //----< test stub >-------------------------------------------- /////////////////////////////////////////////////////////////// // test1 class declaration - example creatable class class test1 : public creatable { public: test1(); void announcer(); static creatable* create(); classID id() const; }; //----< static test1 object - force test1 registration >------- static test1 staticTest1Obj; //----< void constructor - does the registration >------------- test1::test1() { objFactory factory; factory.reg(id(),test1::create); } //----< virtual function displays class identity >------------- void test1::announcer() { std::cout << "\n object of class " << id(); } //----< factory function - creates object >-------------------- creatable* test1::create() { return new test1; } //----< provide class identifier string >---------------------- classID test1::id() const { return "test1"; } // ///////////////////////////////////////////////////////////////////////// // test2 class declaration - example creatable class class test2 : public creatable { public: test2(); void announcer(); static creatable* create(); classID id() const; }; //----< static test2 object - force test1 registration >------- static test2 staticTest2Obj; //----< void constructor - does the registration >------------- test2::test2() { objFactory factory; factory.reg(id(),create); } //----< virtual function displays class identity >------------- void test2::announcer() { std::cout << "\n object of class " << id(); } //----< factory function - creates object >-------------------- creatable* test2::create() { return new test2; } //----< provide class identifier string >---------------------- classID test2::id() const { return "test2"; } // //----< entry point >---------------------------------------------------- void main() { std::cout << "\n Demonstate Object Factory and Creatable Objects " << "\n =================================================\n"; objFactory factory; test1 *pNewTest1 = dynamic_cast(factory.makeObj("test1")); if(pNewTest1) pNewTest1->announcer(); test2 *pNewTest2 = dynamic_cast(factory.makeObj("test2")); if(pNewTest2) pNewTest2->announcer(); std::cout << std::endl; std::cout << "\n The factory delivers, via creatable pointers, objects that" << "\n derive from creatable. Therefore we must use the RTTI" << "\n based dynamic_cast(creatable*) to use derived" << "\n public interface. See the test stub for details."; std::cout << "\n\n"; } #endif