[ create a new paste ] login | about

Link: http://codepad.org/7pgzaaAK    [ raw code | output | fork ]

C++, pasted on Feb 2:
// base class for plugins
class Foo{
public:
	virtual std::string getName()const=0;
	virtual void exercise()const=0;
};

// plugin factory
class FooFactory{
public:
	static Foo*	GetA(std::string s);
	typedef std::map<std::string,Foo*(*)(void)> mapType;
	static mapType& getA();
};

FooFactory::mapType& FooFactory::getA(){static mapType getA;return getA;}
Foo* FooFactory::GetA(std::string s)
{return getA().find(s)!=getA().end()?getA()[s]():0;} // to simplify access

// helper function to add the fun
template<typename T>
Foo* getNew(){	return new T; }

// use the CRTP to automatically register the object with the factory.
template <typename T> struct Reg { Reg() { /*cout << "registering a " << T().getName()<<endl;*/
    FooFactory::getA().insert(std::pair<std::string, Foo*(*)()>(T().getName(), &getNew<T>));} };

template <typename T>
class Foo_reg:public Foo{
public:
Foo_reg(){&reg;}; // using a reff to the static is enough to force initialization of the static earlier
static Reg<T> reg;
};
template <typename T> Reg<T> Foo_reg<T>::reg;

/////////////////
class FooBar:public Foo_reg<FooBar>{ // automatic registration with the factory
public:
    FooBar(){a=10;}
    virtual std::string getName()const{return "Foo Bar";}
    virtual void exercise()const {cout <<a;}
private:
    int a;
};

// exercise the factory and objects.
int main(){
Foo* foo=FooFactory::GetA("Foo Bar");
foo->exercise();
}


Output:
1
10


Create a new paste based on this one


Comments: