用typelist實現RUNTIMECLASS機制

2021-05-23 23:46:57 字數 1917 閱讀 1139

最有名的就是mfc中的runtimeclass機制,它給每個類建立乙個對應的runtimeclass類。然後將所有的runtimeclass類鏈成乙個鍊錶,鍊錶中還記錄了類之間的派生關係。

runtimeclass機制無非可以有兩點好處:

cobject* pascal createobject(lpcstr lpszclassname);

bool iskindof(const cruntimeclass* pclass) const;

特別是第二點,給程式設計帶來很大的靈活性,程式設計師可以在向父類的指標集合中,找出感興趣的子類的指標,然後進行向下型別轉換處理。

for(vector::iterator it = vptrs; it != vptrs.end(); ++it)

if ((*it)->iskindof(getruntimeclass(cconcretea)))

cconcretea* pa = static_cast(*it);

學習了《c++設計新思維》,當時在看完typelist之後什麼感覺也沒有,它能做什麼呢?用它來生成那寵雜的自動生成繼承體系嗎?有多少實際專案會那麼做呢?

經過後來的學習,我至少發現了typelist有兩個地方有用。

詳細的實現可以見這個帖子的討論:http://topic.csdn.net/t/20041009/16/3437898.html

boost::tuple便是借助於typelist實現的。

如:boost::tupletriple(42,3.14,"my first tuple!");

支援這種元組背後的**如下:

可以看到,為typelist增加兩個成員head, tail來儲存不用的型別的值。

看了typelist的兩個應用,現在用它來實現runtimeclass機制如何?

runtimeclass的動態型別的建立功能已經在typelist的第乙個應用——類廠中實現。那麼,如何實現動態型別判斷呢?這時我們要用到編譯期型別偵察的利器:conversion

它可以用來在編譯期偵察t型別是否可以轉換為u型別。

有了這樣乙個強大的類,似乎可以重新定製乙份自己的iskindof。

我第一下想到的就是要製作乙個這個函式

bool iskindof(const char* lpszbase, const char* lpszgenerated)

傳入兩個類名,判斷乙個類是否是另乙個類的子類,但這樣有個問題:兩個引數同時傳入typelist,typelist只能通過遞迴來遍歷它的每乙個型別,因此,在遞迴的任意一層,我只能取得當前層的型別,而不能同時取出list中的兩個型別,這樣的話,我如何同時把兩個對應的字串轉化為對應的型別,從而呼叫conversion?

那麼只能改造iskindof方法,一般來說,動態型別判斷時,需要判斷的目標型別是編譯時已知的,因此,iskindof必須做成模板類

template

bool iskindof(const char* lpszgenerated);

問題解決:**如下:

其中cactor派生自cgameobj, cgraphinstconcrete派生自cgraphinst,cgameobj和cgraphinst沒有關係。結果是

正是所期望的。

這種方法比runtimeclass的好處在於runtimeclass太重了,

typelist方法中每個類只要乙個靜態成員儲存型別名

runtimeclass至少比typelist方式多出兩個靜態成員m_pbaseclass, m_pnextclass,這些靜態成員的關係在typelist中通過conversion很淫的編譯時運算就已經構建了,所以typelist沒有這些多的成員

從速度上來講,我覺得和runtimeclass差不多。只要把不同繼承體系的類分開到不同的typelist中的話,速度應該是不比runtimeclass差。當然,上面的測試**把所有不相干的類都混在一起了,這肯定會增加判定過程。

用棧實現佇列 用佇列實現棧

棧的特點 filo firstinlastout 僅能從棧頂插入,刪除元素。最基本的介面包括push 從棧頂壓入元素 pop 從棧頂彈出元素 佇列的特點 fifo firstinfirstout 僅能從隊頭刪除元素,從隊尾插入元素。最基本的介面包括enque 從隊尾插入元素 deque 從隊頭刪除元...

用棧實現佇列,用佇列實現棧。好玩!!!

因為在資料結構中,棧和佇列長得實在是太像了,將他們拿來比較是不可避免的,棧 後進先出,而佇列 先進先出。同樣是只能在一端進行操作,那麼問題來了,能相互實現?能不能得好好分析一下嘛,如果是用兩個棧來實現佇列,好像這操作可以哦。一下,你就明白!顯然用兩個棧可以實現佇列的功能,就是借助另乙個棧來中轉一下,...

232 用棧實現佇列 225 用佇列實現棧

用棧實現佇列 佇列是先進先出,實現佇列的最直觀的方法是用鍊錶。但本題是要求使用棧。本題兩個stack相互倒,負負得正 class myqueue def init self self.instack self.outstack defpush self,x def pop self if len s...