運行時類型識別,根據基類指針或引用檢索指針或引用所指對象的實際類型函數
要使用RTTI,要求基類中具備虛函數spa
兩種方法支持RTTI:指針
typeid操做符code
dynamic_cast操做符對象
當須要經過基類指針或引用調用不是基類組成部分的派生類成員,就須要將基類指針或引用轉換爲派生類的指針或引用;固然也能夠經過虛函數的方式,可是某些狀況下是不可能使用虛函數的,好比靜態成員函數;見下:繼承
/* * main.cc * * Created on: 2014年1月15日 * Author: root */ #include <stdio.h> class A{ public: static void print(){ printf("A\n"); } virtual ~A(){ ; } /* 基類必需要用虛函數才能使用RTTI */ }; class B:public A{ public: static void print(){ printf("B\n"); } virtual ~B(){ ; } }; int main(int argc,char *argv[]){ A *a=new B; a->print(); /* 若是要調用B版本的print;此時不可能經過虛函數 * 因此必須使用動態類型轉換,即dynamic_cast操做符 */ /* 此時b的做用域爲if塊與if匹配的else塊中 */ if(B *b=dynamic_cast<B*>(a)) b->print(); else a->print(); delete a; return 0; }
dynamic_cast<派生類指針或引用>(基類指針或引用),將基類指針或引用轉換爲同一繼承層次中派生類的指針或引用;作用域
dynamic_cast會進行運行時檢查,若是基類指針或引用所指對象的實際類型不是'<派生類指針或引用>'類型,如:字符串
class A{ virtual ~A(){} }; class B:public A{}; class C:public A{}; int main(int argc,char *argv[]){ A *a=new B; dynamic_cast<C*>(a); /* 此時就會轉換失敗 */ delete a; return 0; }
對於 dynamic_cast<派生類指針>(基類指針):io
轉換失敗的話,返回0;ast
對於 dynamic_cast<派生類引用>(基類引用):
因爲不存在空引用,因此轉換失敗的話,拋出bad_cast異常;
typeid(表達式),返回type_info類型,type_info類是對錶達式的類型的一個包裝,若是有虛函數支持的話,則會返回表達式的運行時實際類型;type_info支持如下操做:
/* 必須包含 <typeinfo> 頭文件才能使用 */ bool operator==(const type_info &__type); bool operator!=(const type_info &__type); /* 判斷兩個類型是否相等 */ const char *name()const; /* 返回類型的字符串表示 */
/* * main.cc * * Created on: 2014年1月15日 * Author: root */ #include <stdio.h> #include <typeinfo> class A{ public: static void print(){ printf("A\n"); } virtual ~A(){ ; } }; class B:public A{ public: static void print(){ printf("B\n"); } virtual ~B(){ ; } }; int main(int argc,char *argv[]){ B b; A *a=&b; if(typeid(*a) ==typeid(B) ) printf("B: %s\n",typeid(*a).name()); else printf("AA\n"); return 0; }