有时候我们希望通过一个字符串创建类,可以通过if..else...来实现
string str = "some_class_name";
如
- if(str==string("class1")){
- class1 xx;
- xx.do();
- }
- else(str ==string("class2")){
- class 2 xx2;
- xx2.do();
- }
- else{
- }
if(str==string("class1")){
class1 xx;
xx.do();
}
else(str ==string("class2")){
class 2 xx2;
xx2.do();
}
else{
}
上面代码不仅丑陋,而且难以扩展,如果我们希望用一个统一的基类来调用函数,如
- string str = "some_class_name";
- Base* s = create_class(str);
- if(s!=NULL)
- s->do();
string str = "some_class_name";
Base* s = create_class(str);
if(s!=NULL)
s->do();
上面的代码就整齐多了,而且以后增加新的类,也不需要修改调用的地方。
同时,如果我们定义的这个Base* create_class(string name)函数能自动帮我们检查有没有一个类名符合输入的字符串,那就完美了。
我们很容易想到,如果有一个全局的map<string, CBase* Create()>来帮我们保存,类名字符串与对应类的新建函数,
输入字符串,通过map找到每个类都有的重载函数CBase* Create() 就可以返回需要的类了。
假设class CBase; class CDerived: CBase;
但是,CBase* Create()怎么新建所需要的类呢,可以用下面这个代码,在执行的时候new一个, 这通过重载很容易实现
static CBase *Create() {
return new CDerived;
}
剩下的问题就是怎么往map里注册这个我们的CBase 和 CDerived了:可以通过类中声明一个辅助类,在辅助类中的构造函数中,插入我们的类名,然后在外类中声明一个static的辅助类,就完成了注册!
上述的代码都可以通过宏展开来完成。
实现代码如下,
- #include <string>
- #include <map>
- #include <iostream>
- using namespace std;
- // 声明具有动态创建的基类
- #define DECLEAR_DYNCRT_BASE(CBase) \
- public: \
- typedef CBase *(*ClassGen)(); /* 声明函数指针*/ \
- static CBase *Create(const string &class_name) /* 工厂函数 */ \
- { \
- std::map<string, ClassGen>::iterator iter = m_class_set.find(class_name); \
- if (m_class_set.end() != iter) \
- { \
- return ((*iter).second)(); \
- } \
- return NULL; \
- } \
- protected: \
- static void Register(const string &class_name, ClassGen class_gen) /* 注册函数 */ \
- { \
- m_class_set.insert(map<string, ClassGen>::value_type(class_name, class_gen)); \
- } \
- static std::map<string, ClassGen> m_class_set; /* 存储子类信息 */
- // 用于实现基类
- #define IMPLEMENT_DYNCRT_BASE(CBase) \
- std::map<string, CBase::ClassGen> CBase::m_class_set;
#include <string>
#include <map>
#include <iostream>
using namespace std;
// 声明具有动态创建的基类
#define DECLEAR_DYNCRT_BASE(CBase) \
public: \
typedef CBase *(*ClassGen)(); /* 声明函数指针*/ \
static CBase *Create(const string &class_name) /* 工厂函数 */ \
{ \
std::map<string, ClassGen>::iterator iter = m_class_set.find(class_name); \
if (m_class_set.end() != iter) \
{ \
return ((*iter).second)(); \
} \
return NULL; \
} \
protected: \
static void Register(const string &class_name, ClassGen class_gen) /* 注册函数 */ \
{ \
m_class_set.insert(map<string, ClassGen>::value_type(class_name, class_gen)); \
} \
static std::map<string, ClassGen> m_class_set; /* 存储子类信息 */
// 用于实现基类
#define IMPLEMENT_DYNCRT_BASE(CBase) \
std::map<string, CBase::ClassGen> CBase::m_class_set;
- // 用于声明一个能够被动态创建的类(用一个全局对象进行注册)
- #define DECLEAR_DYNCRT_CLASS(CDerived, CBase) \
- public: \
- struct CDerived##Register /* 辅助类,用于注册 */ \
- { \
- CDerived##Register() \
- { \
- static bool bRegistered = false; /* 注册子类,保证唯一注册一次 */ \
- if(!bRegistered) \
- { \
- CBase::Register(#CDerived, CDerived::Create); /* 注册子类信息 */ \
- bRegistered = true; \
- } \
- } \
- } ; \
- static CBase *Create() /* 工厂函数 */ \
- { \
- return new CDerived; \
- } \
- static struct CDerived##Register m_t##CDerived##Register;
- // 用于实现一个能被动态创建的类
- #define IMPLEMENT_DYNCRT_CLASS(CDerived) \
- static CDerived::CDerived##Register m_t##CDerived##Register;
// 用于声明一个能够被动态创建的类(用一个全局对象进行注册)
#define DECLEAR_DYNCRT_CLASS(CDerived, CBase) \
public: \
struct CDerived##Register /* 辅助类,用于注册 */ \
{ \
CDerived##Register() \
{ \
static bool bRegistered = false; /* 注册子类,保证唯一注册一次 */ \
if(!bRegistered) \
{ \
CBase::Register(#CDerived, CDerived::Create); /* 注册子类信息 */ \
bRegistered = true; \
} \
} \
} ; \
static CBase *Create() /* 工厂函数 */ \
{ \
return new CDerived; \
} \
static struct CDerived##Register m_t##CDerived##Register;
// 用于实现一个能被动态创建的类
#define IMPLEMENT_DYNCRT_CLASS(CDerived) \
static CDerived::CDerived##Register m_t##CDerived##Register;
- // 声明基类:
- class CBase
- {
- DECLEAR_DYNCRT_BASE(CBase)
- DECLEAR_DYNCRT_CLASS(CBase, CBase)
- public:
- virtual void Print()
- {
- std::cout << "This is base!" << std::endl;
- }
- };
- IMPLEMENT_DYNCRT_BASE(CBase)
- IMPLEMENT_DYNCRT_CLASS(CBase)
// 声明基类:
class CBase
{
DECLEAR_DYNCRT_BASE(CBase)
DECLEAR_DYNCRT_CLASS(CBase, CBase)
public:
virtual void Print()
{
std::cout << "This is base!" << std::endl;
}
};
IMPLEMENT_DYNCRT_BASE(CBase)
IMPLEMENT_DYNCRT_CLASS(CBase)
- //声明继承类
- class CDerived : public CBase
- {
- DECLEAR_DYNCRT_CLASS(CDerived, CBase)
- public:
- virtual void Print()
- {
- cout << "This is derived!" << endl;
- }
- };
- IMPLEMENT_DYNCRT_CLASS(CDerived)
- //声明再继承类
- class ExCDerived : public CDerived
- {
- DECLEAR_DYNCRT_CLASS(ExCDerived, CBase)
- public:
- virtual void Print()
- {
- cout << "This is ExCDerived!" << endl;
- }
- };
- IMPLEMENT_DYNCRT_CLASS(ExCDerived)
- int main()
- {
- CBase* base = CBase::Create("CBase");
- if (base)
- {
- base->Print();
- }
- CBase* base2 = CBase::Create("CDerived");
- if (base2)
- {
- base2->Print();
- }
- CBase* base3 = CBase::Create("ExCDerived");
- if (base3)
- {
- base3->Print();
- }
- return 0;
- }