// 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(){®}; // 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();
}