template<typename T>
class Singleton
{
protected:
Singleton() = default;
public:
static T& inst()
{
static T instance;
return instance;
}
};
#include <map>
#include <string>
#include <functional>
#include <memory>
#include <stdexcept>
template<typename T, typename... Args>
class SingletonFactory : public Singleton<SingletonFactory<T, Args...>>
{
public:
class Register
{
public:
Register(const std::string& type, std::function<std::shared_ptr<T>(Args...)> creator)
{
SingletonFactory<T, Args...>::inst().creator[type] = creator;
}
};
std::shared_ptr<T> create(const std::string& type, Args... args)
{
if (creator.count(type) == 0)
throw std::runtime_error("Invalid Factory instance type: " + type);
return creator.at(type)(args...);
}
protected:
std::map<std::string, std::function<std::shared_ptr<T>(Args...)>> creator;
};
class Object
{
}
typedef SingletonFactory<Object, std::string> ObjectSingletonFactory;
#include <string>
class MyObject : public Object
{
public:
MyObject(std::string name)
{
printf(name.c_str());
}
};
static ObjectSingletonFactory::Register factoryRegister(
"MyObject",
[](std::string name) {
return std::make_shared<MyObject>(name);
});
#include <string>
class MyObject2 : public Object
{
public:
MyObject2(std::string name)
{
printf(name.c_str());
}
};
static ObjectSingletonFactory::Register factoryRegister2(
"MyObject2",
[](std::string name) {
return std::make_shared<MyObject2>(name);
});
int main()
{
auto obj = ObjectSingletonFactory::inst().create("MyObject", "ObjName1");
auto obj2 = ObjectSingletonFactory::inst().create("MyObject2", "ObjName2");
}