前段时间闲时,有时间来看看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);
}
由于现在代码还不是很完善,现在只放出测试版请家谅解,等比较完善的时候在放出源码,共家使用。