C++ 通過運行時類型識別 RTTI(轉)


RTTI(Run-Time Type Identification,通過運行時類型識別)程序能夠使用 基類 指針 或引用來檢查這些指針或引用所指的對象的實際 派生類 型。
RTTI提供了以下兩個非常有用的操作符:
(1)typeid操作符,返回 指針和引用所指的實際類型。
(2) dynamic_cast操作符,將 基類類型的 指針或引用安全地轉換為 派生類型的指針或引用。
 
typeid操縱符會返回一個type_info類,這個類有一個成員函數是name()得到類型名,type_info類構造方法私有,只能由typeid產生,type_info重載了== 和!= ,隱藏了賦值運算符=,所以可以用來比較兩個變量的類型是否相等和不等,但不能賦值。
使用 :type_info x = typeid(對象引用);
typeid實現的原理是使用了友元函數,typeid作為type_info類的友元函數,可以調用私有的構造方法產生type_info對象
typeid接受的參數是引用,如果傳一個A類型的指針,並且指針指向的是A的子類的對象,但typeid返回的依然是對象A的type_info,只有將傳*p才是代表真正的A的子類的對象,這時才會返回A的子類的type_info
 
dynamic_cast操作符只能轉換含有虛函數的類,語法為 dynamic_cast<類型>(表達式),在C++中,向上轉換不需要強制轉換,比如有一個父類的指針p, p =new 子類(); 這樣不會錯,但是有子類的指針cp, cp = p 就不行了,必須用dynamic_cast 進行轉換。dynamic_cast 轉換失敗返回null。
 
后序補全const_cast,static_cast,reinterpret_cast

const_cast

 
用法:const_cast<type_id> (expression)
該運算符用來修改類型的const或volatile屬性。除了const 或volatile修飾之外, type_id和expression的類型是一樣的。
一、常量指針被轉化成非常量的指針,並且仍然指向原來的對象;
二、常量引用被轉換成非常量的引用,並且仍然指向原來的對象;
void foo()
{
const B b1;
//b1.m_iNum = 100; //compile error
/* 可以做如下轉換,體現出轉換為指針類型 */
B *b2 = const_cast<B*>(&b1);
/* 或者左側也可以用引用類型,如果對b3或b4的數據成員做改變,就是對b1的值在做改變 */
B &b3 = const_cast<B&>(b1);
b2 -> m_iNum = 200; //fine
b3.m_iNum = 300;//fine
}
 

static_cast

 
用法:static_cast < type-id > ( expression )
該運算符把expression轉換為type-id類型,但沒有運行時類型檢查來保證轉換的安全性。它主要有如下幾種用法:
①用於 類層次結構中基類(父類)和 派生類(子類)之間指針或引用的轉換。
進行上行轉換(把派生類的指針或引用轉換成基類表示)是安全的;
進行下行轉換(把基類指針或引用轉換成 派生類表示)時,由於沒有動態類型檢查,所以是不安全的。
②用於基本數據類型之間的轉換,如把int轉換成char,把int轉換成enum。這種轉換的安全性也要開發人員來保證。
③把空指針轉換成目標類型的空指針。
④把任何類型的表達式轉換成void類型。
注意:static_cast不能轉換掉expression的const、volatile、或者__unaligned屬性。
 
reinterpret_cast [1]是C++里的 強制類型轉換符。
操作符修改了 操作數類型,但僅僅是重新解釋了給出的對象的比特模型而沒有進行 二進制轉換
 
static_cast在轉換的時候會把數據的二進制進行重新解析,比如float f = 1.333 ,int i = static_cast<int>(f)
i的值為1
reinterpret_cast 則不會重新解析,只會把二進制的值直接賦予給i。

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com