You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
1.6 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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