, , . , , factory ( ).
, , main().
Base.hpp:
#include <unordered_map>
#include <string>
class Base
{
public:
typedef Base * (*base_creator_fn)();
typedef std::unordered_map<std::string, base_creator_fn> registry_map;
virtual ~Base() = default;
static registry_map & registry();
static Base * instantiate(std::string const & name);
};
struct Registrar
{
Registrar(std::string name, Base::base_creator_fn func);
};
Base.cpp:
#include "Base.hpp"
#include <iostream>
registry_map & Base::registry()
{
static registry_map impl;
return impl;
}
Base * Base::instantiate(std::string const & name)
{
auto it = Base::registry().find(name);
return it == Base::registry().end() ? nullptr : (it->second)();
}
Registrar::Registrar(std::string name, Base::base_creator_fn func)
{
Base::registry()[name] = func;
std::cout << "Registering class '" << name << "'\n";
}
Example.hpp:
#include "Base.hpp"
class DerivedExample : public Base
{
static Registrar registrar;
public:
static Base * create() { return new DerivedExample; }
};
Example.cpp:
#include "Example.hpp"
Registrar DerivedExample::registrar("DerivedExample", DerivedExample::create);
main.cpp
#include "Example.hpp"
int main()
{
Base * p = Base::instantiate("DerivedExample");
Base * q = Base::instantiate("AnotherExample");
}
, Registrar, ( ) , , .
( ++, ++ 98:)
virtual ~Base() { }
Base::registry_map::const_iterator it = Base::registry().find(name);