#ifndef CREATABLE_H #define CREATABLE_H /////////////////////////////////////////////////////////////////////// // creatable.h - declares creatable interface and object factory // // ver 2.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 // /////////////////////////////////////////////////////////////////////// /* Module Operations: ================== The creator class defines a creation policy for objects that can be created with an instance of class objFactory. The creator class is template-based where its template parameter defines the class of the object to be created. Creatable classes inherit publically from the creator class to declare and implement two functions: - a create function that returns a new instance of the class via a pointer whose type is the class or a base type. - a function called classID() that returns a string holding the class name. The objFactory class creates an object of the base or any derived class, attached to a base pointer. The user does not need to know the object's type. You need to treat the factory like a smart new operator. It creates an object on the heap. It's up to you to delete it. Public Interface of creatable and objFactory classes ==================================================== objFactory factory; myBaseType *pMyType = factory.makeObj("myDerivedType"); pMyType->memberfun(); // calls myDerivedType::memberfun() delete pMyType; */ // ///////////////////////////////////////////////////////////////////////// // build process // ///////////////////////////////////////////////////////////////////////// // required files: // // creatable.h, creatable.cpp // // // // compiler command: // // cl /GX /GR /DTEST_CREATABLE creatable.cpp // // // // note: /GR enables RTTI which we need in order to use dynamic_cast. // // In the IDE you can enable RTTI on the Project Settings // // menu. Select C/C++ tab and select C++ language from the // // category combo box. Check the box for enabling RTTI. // // // ///////////////////////////////////////////////////////////////////////// /* Maintenance History =================== ver 2.0 : 02 Dec 01 - made factory template based so type of the returned pointer can be set at compile time. ver 1.0 : 01 Dec 01 - first release */ // #pragma warning(disable : 4786) #include #include ///////////////////////////////////////////////////////////////////////// // creator class declaration // - provides a creational policy typedef std::string classID; template class creator { public: virtual ~creator() { } static B* create(); static classID id(); }; //----< returns an object of type D via a type B pointer >--------------- // // will fail to compile unless D is B or derived from B // template B* creator::create() { return new D; } //----< return class name >---------------------------------------------- template classID creator::id() { std::string temp = typeid(D).name(); // returns "class name" int pos = temp.find("class "); if(pos < temp.size()) temp.erase(0,6); return temp; } // ///////////////////////////////////////////////////////////////////////// // objFactory class declaration // // - The odd type T*(*)(), in the second argument of the map is the type // of a function pointer for functions with signature T* somefun(). // - In the reg function, the second declaration is Type arg where Type // is T*(*)() and arg is pFun. template class objFactory { public: objFactory(); static void reg(classID id, T*(*pFun)()); static T* makeObj(classID id); protected: static std::map registry; }; ///////////////////////////////////////////////////////////////////////// // define the static instance of the class registry template std::map objFactory::registry; //----< construct objFactory >------------------------------------------- template objFactory::objFactory() { } //----< register a static member creation function >--------------------- template void objFactory::reg(classID id, T*(*pFun)()) { registry[id] = pFun; int len = registry.size(); } //----< create an instance of a creatable class >------------------------ template T* objFactory::makeObj(classID id) { T *theObject = NULL; int len = registry.size(); std::map::const_iterator entry = registry.find(id); if(entry != registry.end()) theObject = entry->second(); return theObject; } #endif