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

1 month ago
#include <string>
#include <map>
#include <unordered_map>
#include <functional>
#include <type_traits>
/**
* ͨ<EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĺ<EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>ӷ<EFBFBD><EFBFBD>ˣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǻ<EFBFBD> MFC <EFBFBD><EFBFBD>ײ<EFBFBD><EFBFBD>
*/
class ClassFactory
{
public:
static ClassFactory& getInstance()
{
static ClassFactory factor;
return factor;
}
/**
* ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param T <EFBFBD><EFBFBD><EFBFBD>
* \param name <EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>CreateObject ʱͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
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;
}
/**
* ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD>һ<EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD> typeid name ע<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD>
*
*/
template <typename T>
void registerClass()
{
registerClass<T>(typeid(T).name());
}
/**
* ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param T <EFBFBD><EFBFBD><EFBFBD>
* \param Args <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD>ϲ<EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD>޲ι<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܽ<EFBFBD><EFBFBD>޷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>Ĭ<EFBFBD>ϲ<EFBFBD><EFBFBD><EFBFBD>ʱҲ<EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>
* \param name <EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>CreateObject ʱͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
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;
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* \param name ǰ<EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \return <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>򷵻<EFBFBD> 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;
};