C++运⾏时通过字符串实例化类对象
有时候我们希望通过⼀个字符串创建类,可以通过if..来实现
string str = "some_class_name";
[cpp]
1. if(str==string("class1")){
2.      class1 xx;
3.      xx.do();
4.    }
5.    else(str ==string("class2")){
6.      class 2 xx2;
7.      xx2.do();
8.    }
9.    else{
10.    }
if(str==string("class1")){
class1 xx;
xx.do();
}
else(str ==string("class2")){
class 2 xx2;
xx2.do();
}
else{
}
上⾯代码不仅丑陋,⽽且难以扩展,如果我们希望⽤⼀个统⼀的基类来调⽤函数,如
[cpp]
1. string str = "some_class_name";
2. Base* s = create_class(str);
3. if(s!=NULL)
4.    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的辅助类,就完成了注册!
上述的代码都可以通过宏展开来完成。
实现代码如下,
[cpp]
1. #include <string>
2. #include <map>
3. #include <iostream>
4. using namespace std;
5. // 声明具有动态创建的基类
6. #define DECLEAR_DYNCRT_BASE(CBase) \
7. public: \
8.  typedef CBase *(*ClassGen)(); /* 声明函数指针*/ \
9.  static CBase *Create(const string &class_name) /* ⼯⼚函数 */ \
10. { \
11.  std::map<string, ClassGen>::iterator iter = m_class_set.find(class_name); \
12.  if (m_d() != iter) \
13.  { \
14.  return ((*iter).second)(); \
15.  } \
16.  return NULL; \
17.  } \
18. protected: \
19.    static void Register(const string &class_name, ClassGen class_gen) /* 注册函数 */ \
20.  { \
21.  m_class_set.insert(map<string, ClassGen>::value_type(class_name, class_gen)); \
22.  } \
23.  static std::map<string, ClassGen> m_class_set; /* 存储⼦类信息 */
24.
25. // ⽤于实现基类
26. #define IMPLEMENT_DYNCRT_BASE(CBase)  \
27.  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_d() != 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;
1. // ⽤于声明⼀个能够被动态创建的类(⽤⼀个全局对象进⾏注册)
2. #define DECLEAR_DYNCRT_CLASS(CDerived, CBase) \
3. public: \
4.  struct CDerived##Register /* 辅助类,⽤于注册 */ \
5.  { \
6.  CDerived##Register() \
7.  { \
实例化类和实例化对象
8.  static bool bRegistered = false; /* 注册⼦类,保证唯⼀注册⼀次 */ \
9.    if(!bRegistered) \
10.    { \
11.    CBase::Register(#CDerived, CDerived::Create); /* 注册⼦类信息 */ \
12.    bRegistered = true; \
13.    } \
14.  } \
15.  } ; \
16.  static CBase *Create() /* ⼯⼚函数 */ \
17.  { \
18.  return new CDerived; \
19.  } \
20.  static struct CDerived##Register m_t##CDerived##Register;
21.
22. // ⽤于实现⼀个能被动态创建的类
23. #define IMPLEMENT_DYNCRT_CLASS(CDerived) \
24.  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;
1. // 声明基类:
2. class CBase
3. {
4. DECLEAR_DYNCRT_BASE(CBase)
5. DECLEAR_DYNCRT_CLASS(CBase, CBase)
6. public:
7.  virtual void Print()
8.  {
9.  std::cout << "This is base!" << std::endl;
10.  }
11. };
12. IMPLEMENT_DYNCRT_BASE(CBase)
13. 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)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。