#include <iostream>
#include <string>
#include <unordered_map>
#include <memory>
struct IBase
{
virtual ~IBase() = default;
virtual void dosmth() const = 0;
};
struct SomeClass1 : public IBase
{
int i;
SomeClass1() : i(33) {}
SomeClass1(int h) : i(h) {}
void dosmth() const override { std::cout << "SomeClass1: " << i << "\n"; };
};
struct SomeClass2 : public IBase
{
int d;
SomeClass2() : d(43) {}
SomeClass2(int s) : d(s) {}
void dosmth() const override { std::cout << "SomeClass2: " << d << "\n"; };
};
void func1()
{
std::cout << "hello!\n";
}
void func2()
{
std::cout << "bye!\n";
}
struct ClassInfoBase
{
std::function<void()> SomeFunction;
virtual std::unique_ptr<IBase> createInstance() const = 0;
virtual std::unique_ptr<IBase> createInstance(int p) const = 0;
};
template<class T>
struct ClassInfo : public ClassInfoBase
{
std::unique_ptr<IBase> createInstance() const override
{
return std::make_unique<T>();
}
std::unique_ptr<IBase> createInstance(int p) const override
{
return std::make_unique<T>(p);
}
};
struct Mapper
{
std::unordered_map<std::string, std::unique_ptr<ClassInfoBase>> Mappings;
template<class Class, class Function>
void registerClass(const std::string &name, Function f)
{
auto info = std::make_unique<ClassInfo<Class>>();
info->SomeFunction = std::move(f);
Mappings[name] = std::move(info);
}
};
int main()
{
Mapper m;
//register some classes at startup
m.registerClass<SomeClass1>("SomeClass1", func1);
m.registerClass<SomeClass2>("SomeClass2", func2);
//create instances by name (or enum)
auto instance1 = m.Mappings["SomeClass1"]->createInstance();
auto instance2 = m.Mappings["SomeClass1"]->createInstance(2);
auto instance3 = m.Mappings["SomeClass2"]->createInstance();
auto instance4 = m.Mappings["SomeClass2"]->createInstance(8);
m.Mappings["SomeClass1"]->SomeFunction();
instance1->dosmth();
instance2->dosmth();
instance3->dosmth();
instance4->dosmth();
m.Mappings["SomeClass2"]->SomeFunction();
}