標籤:衍生類別 png highlight image 引用 強制類型轉換 foo 使用 類型轉換
通過RTTI,能夠通過基類的
指標或引用來檢索其所指對象的實際類型。c++通過下面兩個操作符提供RTTI。(1)typeid:返回指標或引用所指對象的實際類型。
(2)dynamic_cast:將基類類型的指標或引用安全的轉換為衍生類別型的指標或引用。
對於帶虛函數的類,在運行時執行RTTI操作符,返回動態類型資訊;對於其他類型,在編譯時間執行RTTI,返回靜態類型資訊。
當具有基類的指標或引用,但需要執行衍生類別操作時,需要動態強制類型轉換(dynamic_cast)。這種機制的使用容易出錯,最好以虛函數機制代替之。
dynamic_cast 操作符
如果dynamic_cast轉換指標類型失敗,則返回0;如果轉換參考型別失敗,則拋出一個bad_cast的異常。
可以對值為0的指標使用dynamic_cast,結果為0。
class People{public: People(){} People(int size):m_size(m_size){} virtual ~People(){}private: int m_size;};class Son : public People{public: Son(int type):m_type(type){} virtual ~Son(){} int getType(){return this->m_type ; }private: int m_type;};int main(){ People *p = new People(12); Son *s = new Son(10); // People *p1 = new Son(34); s = dynamic_cast<Son*>(p1) ; cout << typeid(*s).name() << endl; cout << typeid(*p1).name() << endl; try{ Son &tmp = dynamic_cast<Son &>(*p1); cout << tmp.getType() << endl; }catch(bad_cast) { // ???д???; }
typeid操作符
typeid能夠擷取一個運算式的類型:typeid(e)。
如果運算元不是
類類型或者是
沒有虛函數的類,則擷取
其靜態類型;如果運算元是
定義了虛函數的類類型,則計算運行時類型。
— 靜態
typeid最常見的用途是比較兩個運算式的類型,或者將運算式的類型與特定類型相比較。
包含 #include <typeinfo>
struct B {} b, c;struct D : B {} d;int main(){ const std::type_info& tb = typeid(b); const std::type_info& tc = typeid(c); const std::type_info& td = typeid(d); assert(tb == tc); // b和c具有相同的類型 assert(&tb == &tc); // tb和tc引用的是相同的對象 assert(tb != td); // 雖然D是B的子類,但是b和d的類型卻不同 assert(&tb != &td); // tb和td引用的是不同的對象}
二 運行時運行識別
typeid 實現運行時類型識別,必須時一個動態類(含有虛函數 virtual)
struct B { virtual void foo() {} };struct C { virtual void bar() {} };struct D : B, C {};void test() { D d; B& rb = d; C& rc = d; assert(typeid(rb) == typeid(d)); // rb引用的類型與d相同 assert(typeid(rb) == typeid(rc)); // rb引用的類型與rc引用的類型相同}
C 語言Struct 實現運行類型識別 RTTI