C 語言Struct 實現執行型別識別 RTTI

Rocky_Ansi發表於2016-11-02

通過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引用的型別相同
}

 

 

相關文章