程式碼下載:http://download.csdn.net/detail/peibaoyi/5707627突發奇想,想根據類的名字(一個C++的string),建立相應的類執行個體,除了這個string,不用其他的東西。比方說我已經聲明了一個PClassStr這個類,現在我用字串"PClassStr"來建立一個PClassStr這個類的執行個體。google了一下,得到的大多數是有關typeof和typeid相關,進一步就是C++0x,還有個auto。
typeid是萃取出某個C++類(或對象)的資訊,得到一個typeinfo instance,然後就可以根據typeinfo判斷一個類對象是否是某個class的對象,或者是兩個類對象是否同一個class的對象。typeinfo類重定義了==、 != 就是完成了上述的功能,自然也定義了能擷取本類的相關資訊的函數。在這裡派不上用場。
typeof關鍵字貌似只能是GNU C編譯器支援,具體沒考證。具體就是:int *a;typeof(*a) b; //當然b就是int類型了但是並不能滿足我的需求,我只需要根據一個string,就能建立一個對象,就像java中那樣,如果用typeof,那麼似乎我必須得有我想建立的那個類的某個執行個體,正如上面我必須有個跟int類型相關的對象a,也就是我想建立PClassStr這個類的執行個體,那麼我得有PClassStr的某個對象,typeof的功能確實很重要,但是這裡使不上力。
模板類的內嵌類型template <typename T>class PClassStr{ public: typedef T value_type; //....}大體如此,正如vector裡面的 vector<PClassStr>::value_type,跟上面的typeof一樣的,始終跳不出在代碼中要先寫上某個類的類型,然後再寫上變數名這個圈套(如 Type variable)。
其實解決的辦法微軟早就解決了,在設計MFC的時候,微軟就把它搞出來了。侯捷的<<深入淺出MFC>>中已對此深入剖析了一番,這裡我簡述一下,並且從MFC的源碼中抽取出相關的宏實現個小程式,效果還可以~
我們知道MFC中有個類的層次,CObject是頂層類,其他的類都是繼承該類,形成一個類的體系,其實java也是採用這種類體繫結構。我們要在每個定義的類裡面都內嵌一個static結構體(CRuntimeClass),裡面記錄這個類的名字,建立本類對象的函數指標(CreateObject),等等,主要是這兩個欄位。在建立每個類的時候我們會把這個類的CRuntimeClass加入到一個全域鏈表中。這樣給定一個類的名字(一個string),只需要遍曆這個全域的鏈表,找到對應這個string的CRuntimeClass(當然類名是不會重複的),因為這個CRuntimeClass裡面存在一個函數指標,專門用來建立對應類的對象的,如此就實現了我的要求。
在我的小程式中,所有類都繼承自PObject每個類的聲明中都應該包含如下相似代碼,你可以寫成宏定義:
public:
static struct CRuntimeClass classPClassStr;
static struct AFX_CLASSINIT _init_PClassStr;
virtual struct CRuntimeClass* GetRuntimeClass() const;
static PObject* CreateObject();
在類的實現中需要包含如下相似代碼:
struct CRuntimeClass PClassStr::classPClassStr = {
"PClassStr",
sizeof(PClassStr),
0XFFFF,
PClassStr::CreateObject,
(&PObject::classPObject),
NULL, &PClassStr::_init_PClassStr };
struct AFX_CLASSINIT PClassStr::_init_PClassStr(&(PClassStr::classPClassStr));
struct CRuntimeClass* PClassStr::GetRuntimeClass() const
{
return (&PClassStr::classPClassStr);
}
PObject* PClassStr::CreateObject()
{
return new PClassStr;
}
這裡要注意AFX_CLASSINIT結構體的妙用,還有全域鏈表如何管理。
有關解釋具體參見<<深入淺出MFC>>,想看相關宏定義查看MFC架構的原始碼,有關全域鏈表頭參見小程式代碼。
程式中沒有對類的繼承體繫結構進行管理,只是簡單地將所有類加入到單鏈表中,它只是實現了我的想法,要想實現typeof的功能還有很多要做。
--EOF