Last week I integrated the ObjectFactory code from this GameDev article by Robert Geiman. His Listing 3 was the basis for my implementation but I modified it to always use std::string as the id type.
I found one inconvenience while using the code, which was that I had to explicitly register the object types. This removed an aspect of 'plugability' that I desired. I found the solution to this in an article & discussion linked from Robert's, Why Pluggable Factories Rock My Multiplayer World. Specifically this reply by WizHarDx.
So, I developed my own extension to the ObjectFactory code which is as follows:
1. Added a GetCount method to the original ObjectFactory class.
2. Created an ObjectFactoryRegistrar templated class:
template class ObjectFactoryRegistrar{public: ObjectFactoryRegistrar(const char *lpType) : m_sType(lpType) { if(!BaseClassType::ObjFactory) { BaseClassType::ObjFactory = new ObjectFactory(); } BaseClassType::ObjFactory->Register(m_sType); } ~ObjectFactoryRegistrar() { if(BaseClassType::ObjFactory) { BaseClassType::ObjFactory->Unregister(m_sType); } if(BaseClassType::ObjFactory->GetCount() == 0) { delete BaseClassType::ObjFactory; BaseClassType::ObjFactory = 0; } }protected: std::string m_sType;};
3. For each object type I want to register into the factory, a static instance of an ObjectFactoryRegistrar is declared. This registrar handles creating and destroying the related ObjectFactory.
Example Usage:
File: MyBaseObject.h
#include "ObjectFactory.h"class MyBaseObject{public: MyBaseObject(); virtual ~MyBaseObject(); static ObjectFactory *ObjFactory;}
File: MyBaseObject.cpp
#include "MyBaseObject.h"ObjectFactory MyBaseObject::ObjFactory = 0;// rest of implementation...
File: MyDerivedObject.h
#include "MyBaseObject.h"class MyDerivedObject : public MyBaseObject{public: MyDerivedObject(); virtual ~MyDerivedObject(); static ObjectFactoryRegistrar ObjRegistrar;}
File: MyDerivedObject.cpp
#include "MyDerivedObject.h"ObjectFactoryRegistrar MyDerivedObject::ObjRegistrar("Derived");// rest of implementation...
File: Main.cpp
#include "MyBaseObject.h"int main(int argc, char *argv[]){ MyBaseObject *pObj = MyBaseObject::ObjFactory->Create("Derived") // rest of implementation...}
One concern:
That the static pointer, MyBaseClass::ObjFactory, will not be set to 0 before the constructor of the first ObjectFactoryRegistrar is called. If so, bad things will happen. Anyone know if this is undefined behavior or if it will be reliable?