前段時間閑時,有時間來看看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);
}
由于現在代碼還不是很完善,現在只放出測試版請家諒解,等比較完善的時候在放出源碼,共家使用。