Skip to content

Instantly share code, notes, and snippets.

@duckie
Last active December 14, 2015 02:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save duckie/5012381 to your computer and use it in GitHub Desktop.
Save duckie/5012381 to your computer and use it in GitHub Desktop.
C++11 trick to create some classes by their ID names.
#include <string>
#include <map>
#include <iostream>
#include <utility>
#include <functional>
struct Interface {
virtual void method() = 0; // May be a visitor pattern
};
template <class T> Interface* InterfaceBuilder(void) { return new T(); };
class Factory {
using interface_builder_func_type = std::function<Interface*(void)>;
std::map<std::string, interface_builder_func_type> classes_;
static Factory * instance_;
Factory();
public:
static std::string RegisterID(std::string const & id, interface_builder_func_type builder);
static Factory& getInstance();
Interface * newInstance(std::string const & id);
};
Factory* Factory::instance_ = nullptr;
Factory::Factory(){}
Interface * Factory::newInstance(std::string const & id) {
Interface * instance = nullptr;
std::map<std::string, interface_builder_func_type>::const_iterator func_iter = classes_.find(id);
if(func_iter != classes_.end()){
instance = (func_iter->second)();
}
return instance;
}
std::string Factory::RegisterID(std::string const & id, interface_builder_func_type builder) {
Factory & factory = getInstance();
factory.classes_.insert(std::make_pair(id, builder));
return id;
}
Factory& Factory::getInstance() {
if(!instance_) {
instance_ = new Factory();
}
return *instance_;
}
// Here the real shit begins
class MessageStart : public Interface {
public:
MessageStart();
static std::string const ClassId;
virtual void method();
};
std::string const MessageStart::ClassId = Factory::RegisterID("ID1", InterfaceBuilder<MessageStart>);
MessageStart::MessageStart() {}
void MessageStart::method() {
std::cout << "I am a start message !" << std::endl;
}
class MessageStop : public Interface {
public:
MessageStop();
static std::string const ClassId;
virtual void method();
};
std::string const MessageStop::ClassId = Factory::RegisterID("ID2", InterfaceBuilder<MessageStop>);
MessageStop::MessageStop() {}
void MessageStop::method() {
std::cout << "I am an end message !" << std::endl;
}
// Demo
int main() {
Factory & factory = Factory::getInstance();
Interface * msg_start = factory.newInstance("ID1");
msg_start->method();
delete msg_start;
Interface * msg_stop = factory.newInstance("ID2");
msg_stop->method();
delete msg_stop;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment