RTTI


RTTI 全名為 Run-Time Type Information,也有人寫作 Run-Time Type Identification,代表著執行時期取得物件的型態資訊,在 C++ 中,可以使用定義於 type_infotypeid 來實作。

typeid 接受物件,傳回 type_info 實例,具有以下的方法可以操作:

  • before:以 C++ 實作品定義的順序進行兩個型態的順序比較(這個順序與繼承順序無關)。
  • hash_code:型態的雜湊值,相同型態會有相同的雜湊值。
  • name:傳回 C++ 實作品定義的名稱。

來看個簡單範例:

#include <iostream> 
#include <typeinfo> 
using namespace std; 

class Base { 
public: 
    virtual void foo() { 
        cout << "foo" << endl; 
    } 
}; 

class Derived1 : public Base { 
}; 

class Derived2 : public Base { 
}; 

void printTypeInfo(Base *base) {
    const type_info &info = typeid(*base);
    cout << info.name()      << "\t"
         << info.hash_code() << endl;     
}

int main() { 
    Derived1 *derived1 = new Derived1();
    Derived2 *derived2 = new Derived2();

    printTypeInfo(derived1);
    printTypeInfo(derived2);

    return 0;
}

執行結果如下:

8Derived1       2830024626
8Derived2       3384147286

如果你需要基於型態來排序,type_infobefore 方法,是唯一提供順序的方式,可用來定義比較器(comparator)。例如:

#include <iostream> 
#include <typeinfo> 
#include <vector>
#include <algorithm>
using namespace std; 

class Base { 
public: 
    virtual void foo() { 
        cout << "foo" << endl; 
    } 
}; 

class Derived1 : public Base { 
}; 

class Derived2 : public Base { 
}; 

int main() { 
    Derived1 *derived1 = new Derived1();
    Derived2 *derived2 = new Derived2();

    vector<const type_info*> types = {&typeid(derived1), &typeid(derived2)}; 

    sort(
        types.begin(), types.end(), 
        [](const type_info* a, const type_info* b) { return a->before(*b); }
    );

    for_each(
        types.begin(), types.end() , 
        [](const type_info* t) { cout << (*t).name() << endl; }
    );

    return 0;
}