VC实现C++的类的反射机制 | |
来源:中国自学编程网 发布日期:2008-09-03 | |
前段时间闲时,有时间来看看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); } 由于现在代码还不是很完善,现在只放出测试版请大家谅解,等比较完善的时候在放出源码,共大家使用。 | |
联系客服