计算机二级C技巧:VC实现C++的类的反射机制
来源:优易学  2010-1-14 11:35:47   【优易学:中国教育考试门户网】   资料下载   IT书店
  前段时间闲时,有时间来看看JAVA的东西,让我吃惊不小,JAVA 在类的反射机制下开发的不少东西比如STRUTS2,Hibernate等东西是如此的好用,就让我有点羡慕不已,想在VC下也来实现类似的东西,于是开始在网上查找相关资料,结果都是说C++只提供了RTTI没有元数据,不能实现。真是让我比较失望。但是还不甘心,于是就自己动手弄起来,经过两天的苦心钻研,现在终于有了一些眉目,找到了解决方法那就是:
  1.自己动手来建立类的各种信息,比如类的函数名称,函数地址,类的大小等等,具体实现如下:
  BEGIN_MAP_CLASS_FACTORY()
  BEGIN_MAP_CLASS(CUser)
  CREATE_ALL_METHOD(CUser, Name)
  CREATE_ALL_METHOD(CUser, Password)
  CREATE_ALL_METHOD(CUser, Rights)
  CREATE_ALL_METHOD(CUser, Day)
  CREATE_COMM_METHOD(CUser, toString, T_NULL)
  END_MAP_CLASS()
  END_MAP_CLASS_FACTORY()
  这个是用来收集类和其成员信息的,这个根据自己的需要,关心什么就收集什么
  没有办法,只能手工来写,C++不提供,所以相对JAVA还是麻烦一点:-(,不过现在已经比较方便了
  如果能写一个IDE的插件来帮助完成这项工作最好了
  2.有了类的信息还是没有用的,因为没有办法调用,经过一夜的努力,终于写出来一个通用的函数转发器,用此转发器可以调用任意类的函数,和非类的函数。例如:
  INVOKE_METHOD(object, T->Find("SetName"), &std::string("Administrator"));
  3.好了,所有的东西都准备齐全了,让我们来一起体验 C++ 的反射机制吧,下面是具体的例子。
  //试例代码,此代码在VC6和2005上测试通过。
  // 测试类
  class CUser
  {
  public:
  CUser()
  {
  printf("~CUser 00000000000000 invoked.\n");
  }
  ~CUser()
  {
  printf("~CUser 111111111111111 invoked.\n");
  }
  public:
  std::string toString()
  {
  std::ostringstream o;
  o << "m_Name = " << m_Name.c_str() <<
  "\r\nm_Password = " << m_Password.c_str() <<
  "\r\nm_Rights = 0x" << &m_Rights <<
  "\r\nm_Day = " << m_Day << "\r\n";
  return o.str();
  }
  private:
  PRIVATE_ENTRY(std::string, Name);
  PRIVATE_ENTRY(std::string, Password);
  PRIVATE_ENTRY(std::list<std::string>, Rights);
  PRIVATE_ENTRY(LONG, Day);
  };
  //声明要收集的类的信息
  BEGIN_MAP_CLASS_FACTORY()
  BEGIN_MAP_CLASS(CUser)
  CREATE_ALL_METHOD(CUser, Name)
  CREATE_ALL_METHOD(CUser, Password)
  CREATE_ALL_METHOD(CUser, Rights)
  CREATE_ALL_METHOD(CUser, Day)
  CREATE_COMM_METHOD(CUser, toString, T_NULL)
  END_MAP_CLASS()
  END_MAP_CLASS_FACTORY()
  static void TestSamples()
  {
  // 初始化映射工厂
  InitializeMappingFactory();
  CLASS_ITER itra = g_class_Factory.Begin();
  printf("%s", g_class_Factory.toString().c_str());
  CClassTemplate *T = FIND_CLASS_MAP("CUser");
  if(T == NULL)
  return;
  // 创建类对象 调用构造函数
  PVOID object = T->Constructor();
  if(object == NULL)
  return;
  printf("invoke CUser constructor.\n");
  std::string t_Result;
  INITIALIZE_INVOKE_MEMORY();
  // 调用Set 和 Get 方法
  INVOKE_METHOD(object, T->Find("SetName"), &std::string("Administrator"));
  INVOKE_METHOD(object, T->Find("GetName"), &t_Result);
  // 调用Set 和 Get 方法
  INVOKE_METHOD(object, T->Find("SetPassword"), &std::string("ld@123456"));
  INVOKE_METHOD(object, T->Find("GetPassword"), &t_Result);
  // 调用Set 和 Get 方法
  LONG t_Day_i = 1000;
  INVOKE_METHOD(object, T->Find("SetDay"), &t_Day_i);
  LONG t_Day_o = (LONG)INVOKE_METHOD(object, T->Find("GetDay"));
  // 调用Set 和 Get 方法
  std::list<std::string> t_List1, t_List2;
  t_List1.push_back("测试1");
  t_List1.push_back("测试2");
  t_List1.push_back("测试3");
  t_List1.push_back("测试4");
  t_List1.push_back("测试5");
  t_List1.push_back("测试6");
  INVOKE_METHOD(object, T->Find("SetRights"), &t_List1);
  INVOKE_METHOD(object, T->Find("GetRights"), &t_List2);
  std::list<std::string>::iterator itrc;
  for(itrc = t_List2.begin(); itrc != t_List2.end(); itrc++)
  {
  printf("%s\n", itrc->c_str());
  }
  printf("%s content\n%s", T->GetName().c_str(), T->toString(object).c_str());
  // 调用 赋值方法
  CUser t_User;
  INVOKE_METHOD(&t_User, T->Find("operator="), object);
  // 调用析构方法 删除对象
  printf("动态调用析构方法\n");
  T->Destructor(object);
  }
  由于现在代码还不是很完善,现在只放出测试版请大家谅解,等比较完善的时候在放出源码,共大家使用。

责任编辑:cyth

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训