項目中遇到了 RTTI 先學一部分 c++ primer內容
-
運行時類型識別:
程序可以使用基類的指針或者引用來檢索這些指針或引用所指對象的實際派生類型
標準庫提供了兩個操作符:
1. typeid 他可以返回指針或者引用所指向對象的實際類型
2. dynamic_cast 將基類類型的指針或引用安全的轉為派生類的指針或者引用
對于不帶虛函數的類在編譯時期執行,否則在運行期間執行
使用時機:
基類指針調用派生類成員函數的話,一般應使用虛函數,這樣編譯器會根據對象的實際類型來選擇正確的函數。但是某些情況下無法使用虛函數,那么此
時如果需要使用基類指針調用派生類成員函數便需要使用RTTI強制轉換,而且必須檢查轉換是否成功了
(一) Dynamic_cast
dynamic_cast 如果轉換到指針失敗則返回 0 如果轉換到引用類型失敗則拋出 bad_cast 異常
對指針操作:
if(Derived *derivedPtr = dynamic_cast<Derived*> (basePtr)){
//basePtr point to a derived object;
}else{
//basePtr point to a base object;
}
在 if 語句中進行檢查 1.條件代碼內部知道 derivedPtr 的類型 2.不可能在測試代碼和使用代碼中加入代碼,也就是說不會在沒有測試前就使用derivedPtr 3.如果失敗外部不會使用未綁定的指針derivedPtr
對引用操作:
因為不存在空引用所以轉換失敗拋出異常
void f(const Base& b){
try{
const Derived &d = dynamic_cast<const Derived&> (b);
}catch(bad_cast){
}
}
(二) typeid
typeid(e) e是任意的表達式或者類型名
Base *bp;
Derived *dp;
//compare type at run time of two objects
if(typeid(*bp)==typeid(*dp)){
//bp dp point to objects of the same type
}
if(typeid(*bp)==typeid(Derived)){
//bp actually point to a Derived
}
注意typeid 測試的是 *bp 對象
//test always fails: The type of bp if pointer to Base
if(typeid(bp)==typeid(Derived)){
}
Base* 將永遠和Derived類型不同
只有typeid 的操作數是帶虛函數的類的對象的時候,才返回動態類型信息,測試指針返回指針的靜態的,編譯時類型
(三 )type_info 類
作為typeid的返回值 提供
t1==t2 t1!=t2 t.name() 的操作
作為應用例子,可以實現一個類型敏感的相等操作符
friend bool operator == (const base& lhs, const base& rhs){
return typeid(lhs)==typeid(rhs) && lhs.equal(rhs);
}
這樣可以處理基類子類混合的相等判斷了