C++运行时通过字符串实例化类对象


有时候我们希望通过一个字符串创建类,可以通过if..else...来实现

string str = "some_class_name";

  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{
   }

上面代码不仅丑陋,而且难以扩展,如果我们希望用一个统一的基类来调用函数,如

  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的辅助类,就完成了注册!

上述的代码都可以通过宏展开来完成。

 

实现代码如下,

  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_class_set.end() != 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_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;
  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)
  1. //声明继承类  
  2. class CDerived : public CBase  
  3. {  
  4. DECLEAR_DYNCRT_CLASS(CDerived, CBase)  
  5. public:  
  6.  virtual void Print()  
  7.  {  
  8.   cout << "This is derived!" << endl;  
  9.  }  
  10. };  
  11. IMPLEMENT_DYNCRT_CLASS(CDerived)  
  12. //声明再继承类  
  13. class ExCDerived : public CDerived  
  14. {  
  15.  DECLEAR_DYNCRT_CLASS(ExCDerived, CBase)  
  16. public:  
  17.  virtual void Print()  
  18.  {  
  19.   cout << "This is ExCDerived!" << endl;  
  20.  }  
  21. };  
  22. IMPLEMENT_DYNCRT_CLASS(ExCDerived)  
  23.   
  24. int main()  
  25. {  
  26.  CBase* base = CBase::Create("CBase");  
  27.  if (base)  
  28.  {  
  29.   base->Print();  
  30.  }  
  31.  CBase* base2 = CBase::Create("CDerived");  
  32.  if (base2)  
  33.  {  
  34.   base2->Print();  
  35.  }  
  36.  CBase* base3 = CBase::Create("ExCDerived");  
  37.  if (base3)  
  38.  {  
  39.   base3->Print();  
  40.  }  
  41.   return 0;  
  42. }  
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值