VC实现C++的类的反射机制

来源:互联网 发布:招商银行软件中心校招 编辑:程序博客网 时间:2024/04/28 06:04
 前段时间闲时,有时间来看看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);
}
原创粉丝点击