執行時型別識別也是面試時常問的問題,今天整理一下,作為學習和分享~
在存在虛函式表的繼承關係時,每個虛函式表前面都設定有乙個type_info指標,用於支援rtti,rtti是為多型而生成的資訊,包括物件繼承關係,物件本身的描述等,只有具有虛函式的物件才會生成。
執行時型別識別(run-time type identification,rtti)的功能由兩個運算子實現:
這兩個運算子的適用場景為使用基類物件的指標或引用執行某個派生類操作且該操作物件不是虛函式。
一般來講,應該盡量使用虛函式,當操作被定義為虛函式時,編譯器將根據物件的動態型別自動選擇正確的函式版本。假設無法使用虛函式,則使用rtti運算子。
dynamic_cast運算子
其使用形式如下:
dynamic_cast
>
(e)//e必須為乙個有效指標
dynamic_cast
>
(e)//e必須是乙個左值
dynamic_cast
>
(e)//e不能是左值
其中,type必須為乙個類型別,通常情況下該型別中含有虛函式。
e型別轉換成功需滿足以下三個條件中的任意乙個:
若是轉換失敗,dynamic_cast語句的轉換目標為指標型別時結果為0(也叫返回空指標),引用型別時丟擲bad_cast異常且異常定義在typeinfo標準庫標頭檔案中。
**如下
#include
using
namespace std;
classa;
virtual
void
test2()
;};classb:
public a
;virtual
void
test2()
;};voidf(
const a &a)
catch
(bad_cast)
cout <<
"cast successful"
<}int
main()
else
/*為引用型別時的向下轉換*/
a &a =
*p1;
f(a)
;return0;
}
執行結果
cast successful
cast successful
dynamic_cast在向下轉換時提供rtti機制使得其轉換相比於static_cast更為安全。
typeid運算子
為rtti提供的第二個運算子是typeid運算子,它允許程式向表示式請求其物件型別。typeid表示式的形式是typeid(e),其中e可以是任意表示式或型別的名字。typeid操作的結果是乙個常量物件的引用,該物件的型別是標準庫型別type_info或者type_info的公有派生類。
**如下
#include
using
namespace std;
classa;
virtual
void
test2()
;};classb:
public a
;virtual
void
test2()
;};int
main()
if(typeid
(*p2)
==typeid
(b))
cout<<
typeid
(*p2)
.name()
}
執行結果
same
same
1b //編譯器不同,此條執行結果可能稍有差異,這裡博主用的xcode作為ide
在第這兩個if語句中,比較了p1,p2所指向的物件動態型別是否相同。值得注意的是,typeid應該作用於物件,若將*p1改為p1,則**永遠不會被執行。
總結
執行時型別識別(RTTI)
執行時型別識別 rtti 即是程式執行過程中知道某個物件屬於某個類,我們平時用c 程式設計接觸的rtti一般是編譯器的rtti,即是在新版本的vc 編譯器裡面選用 使能rtti 然後載入typeinfo.h檔案,就可以使用乙個叫typeid 的運運算元,它的地位與在c 程式設計中的sizeof 運運...
C 執行時型別識別(RTTI)
執行時型別識別rtti 即run time type identification 主要通過typeid和dynamic cast來實現 typeid操作符 type info實現如下 class type info 應用如下 typeid obj name 列印出指標obj指向的實際的物件型別if...
MFC中的執行時型別識別 RTTI
rtti是runtime type identification的縮寫,中文名為 執行時型別識別 mfc早在編譯器支援rtti之前,就有了這種能力。我們現在要以相同的手法,在console程式中 出來。我希望我的類庫具備iskindof 的能力,能在執行期偵測到某個物件是否屬於某個類,並傳回true...