C++反射机制模拟

反射这个特性在C++中是没有的。所谓反射,自己的认为就是通过一个名字就可创建、调用、获取信息等一系列的操作,这个在脚本语言里面是比较常见的,COM组件也类似,知道个ID名,就可以做很多的工作了。

看看JAVA中的描述:

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为JAVA语言的反射机制。

JAVA反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

反射发挥威力的场所:1.序列化(Serialization)和数据绑定(Data Binding)。2.远程方法调用(Remote Method Invocation RMI)。3.对象/关系数据映射(E/R Mapping)。

虽然没有,但既然我们用的是C++,总是会有办法的~~

ITEM1:动态创建

在实现反射的过程中的第一步要做的可能就是动态创建了,就是用一个类的名字就可以得到这个类的创建函数,从而进行对象的创建。要实现这些,首先对于要反射的类得提供一个能创建自己的回调函数,我们可以使用这个函数来创建这个类的对象,这样,也使得创建活动内聚,减少将来不必要的修改。同时,为了我们可以通过类名获取刚才所说的回调函数,我们就需要一种全局储存结构来保存创建函数和对应类名的映射关系。

这个回调函数就可以是这样的:

static CBaseClass* ClassName::CreateClassName (){

              return new ClassName;

};

在MFC中,我们常使用DECLARE_DYNCREATE宏,这个宏可以使每个CObject的派生类的对象具有运行时动态创建的能力。那么我们也可以使用宏来简化上面实现函数的方法,如下:

#define DEFINE_DYN _CREATE(class_name) /

static CBaseClass * CreateClass## class_name ();

 

#define IMPLIMENT_DYN _CREATE(class_name) /

static CBaseClass * CreateClass## class_name (){  /

       return new class_name;             /

};

分别放入需要创建的类的H文件和CPP文件就可以了~,当然,仅仅这样还不可以,因为我们不但要可以低耦合地创建对象,还需要把对象的创建方法和类名的映射存储起来,那么我们就还需要一个宏:

#define REGISTER_CLASS (class_name) /

RegisterFactory (class_name::CreateClass## class_name, #class_name);

在RegisterFactory函数中,我们需要一种结构,比如Map,将对应关系存储起来,以备以后的使用。

当然,我们也可以使用另一种方法,我们可以创建一个一般类,这个类可以进行映射关系的存储,提取,运行,或者动态映射的功能,我们让我们的反射类继承这个一般类就可以了。还是见代码吧(在2008下使用),如下所示:

(援引自http://blog.csdn.net/wrq147/archive/2010/05/18/5603262.aspx

 

[cpp] view plaincopy
 
  1. #include <string>    
  2. #include <map>    
  3. #include <iostream>  
  4. using namespace std;  
  5. typedef void* (*CreateFuntion)(void);  
  6.   
  7. class ClassFactory  
  8. {  
  9. public:  
  10.         static void* GetClassByName(std::string name)  
  11.         {            std::map<std::string,CreateFuntion>::const_iterator find;  
  12.                 find = m_clsMap.find(name);  
  13.                 if(find==m_clsMap.end())  
  14.   
  15.                 {  
  16.   
  17.                         return NULL;  
  18.   
  19.                 }  
  20.   
  21.                 else  
  22.   
  23.                 {  
  24.   
  25.                         return find->second();  
  26.   
  27.                 }  
  28.   
  29.         }  
  30.   
  31.         static void RegistClass(std::string name,CreateFuntion method)  
  32.   
  33.         {  
  34.   
  35.                 m_clsMap.insert(std::make_pair(name,method));  
  36.   
  37.         }  
  38.   
  39. private:  
  40.   
  41.         static std::map<std::string,CreateFuntion> m_clsMap;  
  42.   
  43. };  
  44.   
  45.    
  46.   
  47. std::map<std::string, CreateFuntion> ClassFactory::m_clsMap;    
  48.   
  49. class RegistyClass  
  50.   
  51. {  
  52.   
  53. public:  
  54.   
  55.         RegistyClass(std::string name, CreateFuntion method)  
  56.   
  57.         {  
  58.   
  59.                 ClassFactory::RegistClass(name, method);  
  60.   
  61.         }  
  62.   
  63. };  
  64.   
  65.   
  66. template<class T, const char name[]>  
  67. class Register  
  68. {  
  69.   
  70. public:  
  71.   
  72.         Register()  
  73.   
  74.         {  
  75.   
  76.                 const RegistyClass tmp=rc;  
  77.   
  78.         }  
  79.   
  80.         static void* CreateInstance()  
  81.   
  82.         {  
  83.   
  84.                 return new T;  
  85.   
  86.         }  
  87.   
  88. public:  
  89.   
  90.         static const RegistyClass rc;  
  91.   
  92. };  
  93.   
  94.    
  95.   
  96. template<class T,const char name[]>  
  97.   
  98. const RegistyClass Register<T,name>::rc(name, Register<T, name>::CreateInstance);  
  99.   
  100.    
  101.   
  102. #define DEFINE_CLASS(class_name) /  
  103.   
  104. char NameArray[]=#class_name;/  
  105.   
  106. class class_name:public Register<class_name, NameArray>  
  107.   
  108.    
  109.   
  110. #define DEFINE_CLASS_EX(class_name,father_class) /  
  111.   
  112. char NameArray[]=#class_name;/  
  113.   
  114. class class_name:public Register<class_name, NameArray>,public father_class  
  115.   
  116.    
  117.   
  118. DEFINE_CLASS(CG)  
  119.   
  120. {  
  121.   
  122. public:  
  123.   
  124.         void Display()  
  125.   
  126.         {  
  127.   
  128.                 printf("I am Here/n");  
  129.   
  130.         }  
  131.   
  132. };  
  133.   
  134.    
  135.   
  136. int main(int tt)  
  137.   
  138. {  
  139.   
  140.           
  141.   
  142.         CG* tmp=(CG*)ClassFactory::GetClassByName("CG");  
  143.   
  144.         tmp->Display();  
  145.   
  146.         return 0;  
  147.   
  148. }  

 

 

ITEM2:动态识别

所谓的RTTI(Run-Time Type Information)也就是运行时类型检查,在C++中的自有动态技术应该就是typeid和dynamic_cast了,找到一段typeid 的例程,如下:

 

[cpp] view plaincopy
 
  1. #include <string.h>   
  2. #include <iostream.h>   
  3. #include <typeinfo.h>   
  4. #include <stdio.h>  
  5.   
  6.    
  7.   
  8. class Base   
  9. {   
  10. public:   
  11.               Base()   
  12.               {   
  13.   
  14.                             strcpy(name,"Base");   
  15.   
  16.               }   
  17.   
  18.                 
  19.   
  20.               virtual void display()   
  21.   
  22.               {   
  23.   
  24.                             cout<<"Display Base."<<endl;   
  25.   
  26.               }   
  27.   
  28. protected:   
  29.   
  30.               char name[64];   
  31.   
  32. };   
  33.   
  34.    
  35.   
  36. class Child1:public Base   
  37.   
  38. {   
  39.   
  40. public:   
  41.   
  42.               Child1()   
  43.   
  44.               {   
  45.   
  46.                             strcpy(name,"Child1");   
  47.   
  48.               }   
  49.   
  50.               void display()   
  51.               {   
  52.   
  53.                             cout<<"Display Child1."<<endl;   
  54.   
  55.               }   
  56.   
  57. };   
  58.   
  59. class Child2:public Base   
  60. {   
  61. public:   
  62.               Child2()   
  63.               {   
  64.   
  65.                             strcpy(name,"Child2");   
  66.   
  67.               }   
  68.   
  69.               void display()   
  70.   
  71.               {   
  72.   
  73.                             cout<<"Display Child2."<<endl;   
  74.   
  75.               }   
  76.   
  77. };   
  78.   
  79. void Process(Base *type)   
  80. {   
  81.   
  82.               if( (typeid(Child1)) == (typeid(*type)) )   
  83.               {   
  84.   
  85.                             ((Child1*)type)->display();   
  86.               }   
  87.   
  88.               else if( (typeid(Child2)) == (typeid(*type)) )   
  89.   
  90.               {   
  91.                             ((Child2*)type)->display();   
  92.               }   
  93.               else   
  94.               {   
  95.                             cout<<"Unknow type!"<<endl;   
  96.               }   
  97.   
  98. }   
  99.   
  100. int main(void)   
  101. {   
  102.               Base *pT1 = new Child1();   
  103.               Base *pT2 = new Child2();   
  104.               Process(pT1);   
  105.               Process(pT2);   
  106.   
  107.               printf("OK/n");   
  108.               return 0;   
  109.   
  110. }   

 

注意:
1.#include "typeinfo.h" 
2.编译选项/GR setting ->c++ -> c++ language -> Enable Run-Time Type Infomation 
3.typeid的使用

posted on 2013-10-13 15:21  AAAAAApple  阅读(707)  评论(0编辑  收藏  举报

导航