Thursday, May 15, 2008

factory


#include <map>
#include <string>
#include <iostream>
using namespace std;

#include <boost/function.hpp>
#include <boost/bind.hpp>

class Base;

class Factory
{
public:
typedef boost::function<Base* ()> Creator;
typedef map<string, Creator> CreatorMap;

Base* allocate(const string& className_) const;
bool registerCreator(const string& className_, Creator creator_);
bool deregister(const string& className_);

static Factory* instance();

private:
CreatorMap _creatorMap;
static Factory* _instancePtr;
};

template<class Base, class Derived>
class Registrar
{

public:
Registrar()
{
cout << "registering:" << Derived::className() << endl;
Factory::instance()->registerCreator(Derived::className(),
boost::bind(&Registrar::create, this));
}

Base* create()
{
return new Derived;
}

};


#endif



#include <Factory.H&gt

Factory::Factory* Factory::_instancePtr;

bool Factory::registerCreator(const string& className_, Creator creator_)
{
return _creatorMap.insert(CreatorMap::value_type(className_, creator_)).second;
}

bool Factory::deregister(const string& className_)
{
return _creatorMap.erase(className_) == 1;
return true;
}

Base* Factory::allocate(const string& className_) const
{
CreatorMap::const_iterator i = _creatorMap.find(className_);
if(i != _creatorMap.end())
{
return (*i).second();
}
else
return NULL;
}

Factory* Factory::instance()
{
if(_instancePtr==NULL)
{
_instancePtr = new Factory();
}
return _instancePtr;
}
---

static Registrar registration;

string Derived1::className()
{
return "Derived1";
}