#include <string>
#include <map>
#include <iostream>
class Whatever {
public:
// контракт
virtual void foo() = 0;
};
class WhateverFactory {
public:
typedef Whatever* (*WhateverCtor)();
static void registerClass(const std::string &name, WhateverCtor ctor) {
if ( m_plugins.find(name) == m_plugins.end() ) {
m_plugins[name] = ctor;
}
}
static bool isRegistered(const std::string &cls) {
return m_plugins.find(cls) != m_plugins.end();
}
static Whatever* createInstanceOf(const std::string &name) {
std::map<std::string, WhateverCtor>::iterator ctor;
if ( (ctor = m_plugins.find(name)) != m_plugins.end() ) {
return ctor->second();
} else {
return NULL;
}
}
private:
WhateverFactory() {}
static std::map<std::string, WhateverCtor> m_plugins;
};
std::map<std::string, WhateverFactory::WhateverCtor> WhateverFactory::m_plugins;
class HelloWorld : public Whatever {
public:
HelloWorld() : m_message("Hello, World!") {}
void foo() {
std::cout << m_message << std::endl;
}
static HelloWorld* create() {
return new HelloWorld;
}
private:
std::string m_message;
};
void load() {
WhateverFactory::registerClass("HelloWorld", reinterpret_cast<WhateverFactory::WhateverCtor>(HelloWorld::create));
}
int main() {
load();
Whatever *w = WhateverFactory::createInstanceOf("HelloWorld");
if ( w ) {
w->foo();
}
return 0;
}
I2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPG1hcD4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKY2xhc3MgV2hhdGV2ZXIgewpwdWJsaWM6CiAgICAvLyDQutC+0L3RgtGA0LDQutGCCiAgICB2aXJ0dWFsIHZvaWQgZm9vKCkgPSAwOwp9OwoKY2xhc3MgV2hhdGV2ZXJGYWN0b3J5IHsKcHVibGljOgogICAgdHlwZWRlZiBXaGF0ZXZlciogKCpXaGF0ZXZlckN0b3IpKCk7CgogICAgc3RhdGljIHZvaWQgcmVnaXN0ZXJDbGFzcyhjb25zdCBzdGQ6OnN0cmluZyAmbmFtZSwgV2hhdGV2ZXJDdG9yIGN0b3IpIHsKICAgICAgICBpZiAoIG1fcGx1Z2lucy5maW5kKG5hbWUpID09IG1fcGx1Z2lucy5lbmQoKSApIHsKICAgICAgICAgICAgbV9wbHVnaW5zW25hbWVdID0gY3RvcjsKICAgICAgICB9CiAgICB9CgogICAgc3RhdGljIGJvb2wgaXNSZWdpc3RlcmVkKGNvbnN0IHN0ZDo6c3RyaW5nICZjbHMpIHsKICAgICAgICByZXR1cm4gbV9wbHVnaW5zLmZpbmQoY2xzKSAhPSBtX3BsdWdpbnMuZW5kKCk7CiAgICB9CgogICAgc3RhdGljIFdoYXRldmVyKiBjcmVhdGVJbnN0YW5jZU9mKGNvbnN0IHN0ZDo6c3RyaW5nICZuYW1lKSB7CiAgICAgICAgc3RkOjptYXA8c3RkOjpzdHJpbmcsIFdoYXRldmVyQ3Rvcj46Oml0ZXJhdG9yIGN0b3I7CiAgICAgICAgaWYgKCAoY3RvciA9IG1fcGx1Z2lucy5maW5kKG5hbWUpKSAhPSBtX3BsdWdpbnMuZW5kKCkgKSB7CiAgICAgICAgICAgIHJldHVybiBjdG9yLT5zZWNvbmQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICB9Cgpwcml2YXRlOgogICAgV2hhdGV2ZXJGYWN0b3J5KCkge30KCiAgICBzdGF0aWMgc3RkOjptYXA8c3RkOjpzdHJpbmcsIFdoYXRldmVyQ3Rvcj4gbV9wbHVnaW5zOwp9OwoKc3RkOjptYXA8c3RkOjpzdHJpbmcsIFdoYXRldmVyRmFjdG9yeTo6V2hhdGV2ZXJDdG9yPiBXaGF0ZXZlckZhY3Rvcnk6Om1fcGx1Z2luczsKCmNsYXNzIEhlbGxvV29ybGQgOiBwdWJsaWMgV2hhdGV2ZXIgewpwdWJsaWM6CiAgICBIZWxsb1dvcmxkKCkgOiBtX21lc3NhZ2UoIkhlbGxvLCBXb3JsZCEiKSB7fQoKICAgIHZvaWQgZm9vKCkgewogICAgICAgIHN0ZDo6Y291dCA8PCBtX21lc3NhZ2UgPDwgc3RkOjplbmRsOwogICAgfQoKICAgIHN0YXRpYyBIZWxsb1dvcmxkKiBjcmVhdGUoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBIZWxsb1dvcmxkOwogICAgfQoKcHJpdmF0ZToKICAgIHN0ZDo6c3RyaW5nIG1fbWVzc2FnZTsKfTsKCnZvaWQgbG9hZCgpIHsKICAgIFdoYXRldmVyRmFjdG9yeTo6cmVnaXN0ZXJDbGFzcygiSGVsbG9Xb3JsZCIsIHJlaW50ZXJwcmV0X2Nhc3Q8V2hhdGV2ZXJGYWN0b3J5OjpXaGF0ZXZlckN0b3I+KEhlbGxvV29ybGQ6OmNyZWF0ZSkpOwp9CgppbnQgbWFpbigpIHsKICAgIGxvYWQoKTsKICAgIFdoYXRldmVyICp3ID0gV2hhdGV2ZXJGYWN0b3J5OjpjcmVhdGVJbnN0YW5jZU9mKCJIZWxsb1dvcmxkIik7CiAgICBpZiAoIHcgKSB7CiAgICAgICAgdy0+Zm9vKCk7CiAgICB9CgogICAgcmV0dXJuIDA7Cn0=