This will only work if all the necessary classes are derived from some common base class, and you will usually be limited to using the base interface (although you can get around this with some extra effort). Here is one approach:
#include <map>
#include <string>
class Base
{
typedef Base * (*crfnptr)(const std::string &);
typedef std::map<std::string, crfnptr> CreatorMap;
static CreatorMap creators;
public:
virtual ~Base() { }
Base * clone() const { return new Base(*this); }
static Base * create_from_string(std::string name)
{
CreatorMap::const_iterator it = creators.find(name);
return it == creators.end() ? NULL : it->first();
}
static void register(std::string name, crfnptr f)
{
creators[name] = f;
}
};
Now you can add new derived classes from your new code:
#include "immutable_core.hpp"
class Foo : public Base
{
public:
Foo * clone() const { return new Foo(*this); }
static Foo * create() { return new Foo; }
};
Base::register("Foo", &Foo::create);
To create a class, you simply call Base * p = Base::create_from_string("Foo");.
source
share