#include #include #include #include #include /** * 通过字符串创建对象的工厂类,这里面的函数全部用小陀峰了,大陀峰老是和 MFC 宏撞名 */ class ClassFactory { public: static ClassFactory& getInstance() { static ClassFactory factor; return factor; } /** * 注册类 * \param T 类本身 * \param name 名称,CreateObject 时通过这个名称来创建对象 */ template void registerClass(const std::string& name) { static_assert(std::is_class::value); auto f = []() { return new T(); }; m_map[name] = f; } /** * 注册类 * 提供一个通过 typeid name 注册的简易用法 * */ template void registerClass() { registerClass(typeid(T).name()); } /** * 注册类 * \param T 类本身 * \param Args 类构造函数的默认参数 * 如果某个类没有无参构造函数,没有这个功能将无法创建对象 * 或者我们想指定默认参数时也能用到 * \param name 名称,CreateObject 时通过这个名称来创建对象 */ template void registerClass(const std::string& name, Args&&... args) { static_assert(std::is_class::value); auto f = [args...]() { return new T(std::forward(args)...); }; m_map[name] = f; } /** * 创建对象 * * \param name 前面注册的字符串名称 * \return 如果有注册,反而该类对象的指针,否则返回 nullptr */ void* createObject(const std::string& name) const { if (m_map.find(name) != m_map.end()) { return m_map.at(name)(); } return nullptr; } private: ClassFactory() { } std::unordered_map> m_map; };