RTTI定義:
RTTI:Run Time Type Identification,運行時類型識別:指程序能夠使用基類的指針或引用來檢索其所指對象的實際派生類型
使用方式:
C++中有幾個個操作符提供RTTI:
typeid操作符:返回指針或引用所指對象的實際類型dynamic_cast操作符:將基類類型的指針或引用安全地轉換為派生類型的指針和引用type_info:很少直接使用,但是需要了解一下,type_info的定義是由編譯器定的,但是共同的是它包含一個name()函數注:這些操作符只為帶有一個或多個虛函數的類返回動態類型信息—-即在運行時執行RTTI操作符,對于其他類型則返回靜態類型的信息—即在編譯時計算RTTI操作符
詳細介紹:
typeid的使用:
#include <iostream>#include <typeinfo> //添加的頭文件using namespace std;class Base1{ };class Derive1 : public Base1{ };class Base2{ virtual void fun( void ) { }};class Derive2 : public Base2{ };class Derive22 : public Base2{ };int main( void ){ // sample1: cout << typeid(1.1f).name() << endl;// 輸出float // sample2: Derive1 d1; Base1& b1 = d1; cout << typeid(b1).name() << endl; // 輸出"class Base1",因為Derive1和Base1之間沒有多態性 // sample3: Derive2 d2; Base2& b2 = d2; cout << typeid(b2).name() << endl; // 輸出"class Derive2",因為Derive1和Base1之間有了多態性 // sample4: Derive2 *d22; Base2 *b22; cout<<boolalpha<<(typeid(*d22)==typeid(*b22))<<endl; //輸出true,typeid(*d22)==typeid(Base2):輸出false // sample5: Base1 *b=new Derive1(); cout<<typeid(b).name()<<endl; //輸出class Base1 * cout<<typeid(*b).name()<endl; //輸出class Derive1 return 0;}dynamic_cast的使用:
#include <iostream>#include <typeinfo>using namespace std;class Base2{ virtual void fun( void ) { }};class Derive2 : public Base2{ };class Derive22 : public Base2{ };//指針強制轉化失敗后可以比較指針是否為零,而引用卻沒辦法,所以引用制轉化失敗后拋出異常// 指針轉換:Derive2 d2;Base2& b2 = d2;Derive2* pb1 = dynamic_cast<Derive2*>(&b2);cout << boolalpha << (0!=pb1) << endl; // 輸出"true",因為b2本身就是Derive2Derive22* pb2 = dynamic_cast<Derive22*>(&b2);cout << boolalpha << (0!=pb2) << endl; // 輸出"false",因為b2本身就是Derive2// 引用轉化:try { Derive2& rb1 = dynamic_cast<Derive2&>(b2); cout << "true" << endl;} catch( bad_cast ){ cout << "false" << endl;}try { Derive22& rb2 = dynamic_cast<Derive22&>(b2); cout << "true" << endl;} catch( ... ) {// 應該是 bad_cast,但不知道為什么在VC++6.0中卻不行 cout << "false" << endl;}typeid(pa)返回的是指針類型,如果要返回對象的類型需要使用引用或者對象作為參數傳遞給typeid
dynamic_cast是個運行時操作,但是它完全依賴虛函數表,如果某個兩個類之間有繼承關系,但是沒有虛函數,那么dynamic_cast不能進行轉化,也不能從void *都某個具體類的轉化,會報告編譯時錯誤
注意事項總結:
dynamic_cast的注意事項:
1.只能用于指針和引用之間的轉換2.要轉換的類型中必須包含虛函數3.轉換成功返回子類的地址,失敗返回NULLtypeid的注意事項:
1.type_id返回type_info對象的引用2.如果想通過基類的指針獲得派生類的數據類型,基類必須帶有虛函數3.只能獲得對象的實際類型新聞熱點
疑難解答
圖片精選