動態創建對很多人來說,都不陌生,在一些大型項目中是比較常見的,也是MFC的核心機制,隨着C++新標準的演化,很多東西都可以很簡單的就實現。
實現代碼:
#include <vector>
#include <functional>
#include "noncopyable.h"
#include "singleton.h"
#include "anyval.h"
#define PRIVATE_REG_DYNCREATE_4(class_name, baseName1, baseName2, baseName3)
class class_name##Register {
private:
static ClassRegistor<class_name> reg_;
};
ClassRegistor<class_name> class_name##Register::reg_(#class_name, #baseName1, #baseName2, #baseName3)
#define PRIVATE_REG_DYNCREATE_3(class_name, baseName1, baseName2)
class class_name##Register {
private:
static ClassRegistor<class_name> reg_;
};
ClassRegistor<class_name> class_name##Register::reg_(#class_name, #baseName1, #baseName2)
#define PRIVATE_REG_DYNCREATE_2(class_name, baseName)
class class_name##Register {
private:
static ClassRegistor<class_name> reg_;
};
ClassRegistor<class_name> class_name##Register::reg_(#class_name, #baseName)
#define PRIVATE_REG_DYNCREATE_1(class_name) PRIVATE_REG_DYNCREATE_2(class_name, class_name)
#define PRIVATE_MACRO_VAR_ARGS_IMPL_COUNT(_1,_2,_3,_4,_5,_6,_7,_8,_9, N, ...) N
#define PRIVATE_MACRO_VAR_ARGS_IMPL(args) PRIVATE_MACRO_VAR_ARGS_IMPL_COUNT args
#define COUNT_MACRO_VAR_ARGS(...) PRIVATE_MACRO_VAR_ARGS_IMPL((__VA_ARGS__,10,9,8,7,6,5 4,3,2,1,0))
#define PRIVATE_MACRO_CHOOSE_HELPER2(M, count) M##count
#define PRIVATE_MACRO_CHOOSE_HELPER1(M, count) PRIVATE_MACRO_CHOOSE_HELPER2(M, count)
#define PRIVATE_MACRO_CHOOSE_HELPER(M, count) PRIVATE_MACRO_CHOOSE_HELPER1(M, count)
//實現宏不定參數的重載
#ifdef WIN32
//EXPAND 用於解決windows上編譯器將__VA_ARGS__展開成一個參數的問題
#define EXPAND(...) __VA_ARGS__
#define REG_DYNCREATE(...) EXPAND(PRIVATE_MACRO_CHOOSE_HELPER(PRIVATE_REG_DYNCREATE_, COUNT_MACRO_VAR_ARGS( __VA_ARGS__))( __VA_ARGS__))
#else
#define REG_DYNCREATE(...) PRIVATE_MACRO_CHOOSE_HELPER(PRIVATE_REG_DYNCREATE_, COUNT_MACRO_VAR_ARGS( __VA_ARGS__))( __VA_ARGS__)
#endif
#define DYN_CREATE(objName) CObjectFactoryAgent::get_instance().CreateObject(objName)
class CObjectFactory
{
public:
template<typename T>
void RegisterObject(const char* objName)
{
std::function<void* ()> function = []() {
return new T;
};
m_creatorMap[objName] = AnyVar(function);
}
void *CreateObject(const std::string &objName)
{
if(m_creatorMap.find(objName) == m_creatorMap.end())
{
return nullptr;
}
AnyVar resolver = m_creatorMap[objName];
std::function<void* ()> func = any_cast<std::function<void* ()>>(resolver);
return func();
}
private:
std::map<std::string, AnyVar> m_creatorMap;
};
typedef Singleton<CObjectFactory> CObjectFactoryAgent;
//運行時類對象管理
class CRuntimeClass
{
//運行時類對象
struct CRuntimeNode
{
//類名稱
std::string m_strClassName;
//繼承類
std::vector<CRuntimeNode*> m_vecInherit;
};
public:
//判斷A是B的基類
bool IsBaseOf(const std::string& baseName, const std::string& objName)
{
auto itFind = m_runtimeNode.find(objName);
if(itFind == m_runtimeNode.end())
{
return false;
}
for(auto item : itFind->second.m_vecInherit)
{
if(item->m_strClassName == baseName)
{
return true;
}
if(IsBaseOf(baseName, item->m_strClassName))
{
return true;
}
}
return false;
}
template<typename... Args >
void RegisterInherit(const char* objName, const char* baseName, Args... args)
{
CRuntimeNode& node = GetRunNode(objName);
if(std::string(objName) != baseName)
{
CRuntimeNode& inhNode = GetRunNode(baseName);
node.m_vecInherit.push_back(&inhNode);
}
RegisterInherit(objName, args...);
}
void RegisterInherit(const char* objName, const char* baseName)
{
CRuntimeNode& node = GetRunNode(objName);
if(std::string(objName) != baseName)
{
CRuntimeNode& inhNode = GetRunNode(baseName);
node.m_vecInherit.push_back(&inhNode);
}
}
CRuntimeNode& GetRunNode(const char* objName)
{
if(m_runtimeNode.find(objName) == m_runtimeNode.end())
{
m_runtimeNode[objName] = CRuntimeNode{objName, {}};
}
return m_runtimeNode[objName];
}
private:
//保持所有對象
std::map<std::string, CRuntimeNode> m_runtimeNode;
};
typedef Singleton<CRuntimeClass> CRuntimeClassAgent;
template<typename T>
class ClassRegistor
{
public:
template<typename... Args >
ClassRegistor(const char* objName, Args... args)
{
CObjectFactoryAgent::get_instance().RegisterObject<T>(objName);
CRuntimeClassAgent::get_instance().RegisterInherit(objName, args...);
}
private:
void do_nothing(ClassRegistor const &) {}
};
測試代碼:
class Test
{
public:
Test()
{
std::cout << "Create Test" << std::endl;
}
};
REG_DYNCREATE(Test);
class Shape
{
public:
virtual void Draw() = 0;
virtual ~Shape() {}
};
class Circle : public Shape
{
public:
void Draw()
{
std::cout << "Circle" << std::endl;
}
~Circle(){};
};
REG_DYNCREATE(Circle, Shape);
class Square : public Shape
{
public:
void Draw()
{
std::cout << "Square" << std::endl;
}
~Square(){};
};
REG_DYNCREATE(Square, Shape);
class Rectangle : public Shape
{
public:
void Draw()
{
std::cout << "Rectangle" << std::endl;
}
~Rectangle(){};
};
REG_DYNCREATE(Rectangle, Shape);
//動態創建
int main()
{
std::cout << "開始" << std::endl;
Shape *ps;
ps = static_cast<Shape *>(DYN_CREATE("Circle"));
ps->Draw();
delete ps;
ps = static_cast<Shape *>(DYN_CREATE("Square"));
ps->Draw();
delete ps;
ps = static_cast<Shape *>(DYN_CREATE("Rectangle"));
ps->Draw();
delete ps;
auto ptr = static_cast<Test *>(DYN_CREATE("Test"));
if(CRuntimeClassAgent::get_instance().IsBaseOf("Shape", "Square"))
{
std::cout << "shape is base of Square" << std::endl;
}
return 0;
}