C RTTI的簡單實現 一

2021-07-31 08:33:17 字數 3580 閱讀 8499

為了加深對rtti的理解,嘗試實現了乙個rtti系統。不過做的比較簡陋,功能如下

typeid的識別利用虛函式實現,利用虛函式的性質可以讓物件輸出真正的型別標誌,而不會被其宣告的型別所改變。為了安全的造型,實現了乙個繼承鏈。在系統內,每個類的宣告裡會加上乙個s_rttinode,用於儲存繼承資訊,包括本類名,父親的繼承資訊和派生類等繼承資訊。這樣繼承的關係就被串聯起來了。定義如下:

////繼承鏈結構體定義/////

typedef struct tagrtti_treertti_tree;

// 單繼承結構如下:

// a

// / \

// b c

// | / \

// d e f

//

另外為了快速向上造型,對整個樹進行了索引。如e可以向上為a和c,但是不允許為b。

#include

#include

#include

#include

using namespace std;

////繼承鏈結構體定義/////

typedef struct tagrtti_treertti_tree;

//////

//////

//////

//////

//////

//////

//////

//////

///////

//////

//////rtti實現

//////

//////

//////

//////

//////

//////

//////

//////

//////

//繼承鏈節點索引

hash_map g_rtti_map;

///構造rtti id

#define my_rtti(class_name) \

public: \

static rtti_tree s_rttinode; \

virtual

const

char * typeid()

//構造rtti繼承結構

#define end_declare_class(class_name,f_class_name) \

rtti_tree class_name::s_rttinode=rtti_create_link("duco|"

#class_name);

//構造rtti繼承結構

#define end_super_declare_class(class_name) \

rtti_tree class_name::s_rttinode=rtti_create_link("duco|"

#class_name);

//構造繼承鏈 超級父親

templatertti_tree rtti_create_link(const

char *pname)

//構造繼承鏈 普通類

templatertti_tree rtti_create_link(const

char *pname)

//對映表,索引整棵樹

string str(pname);

g_rtti_map[str]=&(mt::s_rttinode);

return t;

}///

//////

//////

//////

//////

//////

//////

//////

//////

////

//////

//////dynamic_cast 實現

//////

//////

//////

//////

//////

//////

//////

//////

//////

template//待轉化類和super類

type *my_dynamic_cast(s *s)

return null;

}///

//////

//////

//////

//////

//////

//////

//////

//////

////

//////

//////demo

//////

//////

//////

//////

//////

//////

//////

//////

//////

/// 說明 1.只支援單繼承體系

/// 2.系統必須有個超級類,作為一切類的最上層父類

/// 3.手動新增my_rtti和end_super_declare_class巨集

/// 4.實現了動態造型

//base 類

class shape ;

};end_super_declare_class(shape)

//circle

class circle:public shape ;

};end_declare_class(circle,shape)

//rect

class rect:public shape ;

};end_declare_class(rect,shape)

//red-rect

class redrect:public rect ;

};end_declare_class(redrect,rect)

//// shape

// / \

// rect circle

// |

// redrect

//int main()

昨天晚上查了一些rtti的資料,其實自己理解的還不夠深刻。據說c++物件模型那本書有詳細,可能會過短時間再看一下,把自己的實現改進一些,比如支援多繼承等。

另外記錄下在實現時遇到的困難。剛開始沒有理清思路,若想獲取乙個類的真實資訊,需要使用虛函式來實現。如果使用類的靜態變數或者函式是沒辦法實現的,因為使用靜態變數前提是我要知道類資訊,而我本來的需求就是動態去獲取類資訊。所以c++的dynamic_cast依賴於虛表。我的實現雖然沒有直接利用虛表,但是建立的繼承鏈本質上是利用了虛表(用其內容構建索引)。

而繼承鏈又是另一回事了,繼承鏈可以認為是靜態的。它儲存的是類之間的關係,跟具體物件無關。所以最後實現是在類宣告中嵌入乙個靜態變數。最後因為要初始化靜態變數,我需要實現乙個初始化函式,而這個函式的變數是類名,所以可以看到我這部分實現不得不使用模板函式:templatertti_tree rtti_create_link(const char *pname);

C RTTI的簡單實現 二

前不久寫了個 c rtti的簡單實現 一 是在查了一些rtti資料後自己倒騰出來的。近日重看 一兩年前看的忘的東西挺多的 深入淺出mfc 看到候老師關於mfc六個 中的rtti實現,對比了下自己的設計,下面總結一下。整體的巨集定義很類似,乙個靜態變數,乙個虛函式返回真實型別。超級父類的特殊處理。資料...

關於C RTTI中typeid()的原理

一直不了解c 中如何判斷乙個例項的類別,只知道用typeid 就好,找了好多資料也都是說關於typeid 怎麼用,對於原理很少談到。於是偶然間我發現了一句話 典型的rtti是通過在vtable中放乙個額外的指標來實現的。恍然大悟,於是試驗了一下。class fa virtual int get cl...

A 演算法(一) 簡單實現

最近準備參加海康威視的乙個軟體挑戰賽 需要用到路徑搜尋的演算法,參考了網上的一些案例,自己實現了乙個簡單的a 演算法。a 演算法是一種啟發式的路徑搜尋演算法。對於地圖中的每乙個節點,我們記錄起點到該節點的消耗g,估算該節點到終點的消耗h 並不是準確值,有多種估算方法,簡單的比如歐氏距離 已經兩者之和...