6.0 C++遠征:運行時類型識別RTTI

4-1運行時類型識別RTTI

[TOC]

1.RTTI

? Run-Time Type Identification

? 運行時類型識別

  • 使程序能夠獲取由基指針或引用所指向的對象的實際派生類型,即允許“用指向基類的指針或引用來操作對象”的程序能夠獲取到“這些指針或引用所指對象”的實際派生類型。

2.操作符typeid

? 等同于sizeof這類的操作符。

? 返回結果是名為type_info的標準庫類型的對象的引用。

? 頭文件typeinfo

  • 它的表達式有下圖兩種形式:
NAME TYPEID TYPE
typeid 類型ID typeid(type)
typeid 運行時刻類型ID typeid(expr)
// type_info類的源碼
class type_info {
  public:
    const char *name() const;
    bool operator==(const type_info& rhs) const;
    bool operator!=(const type_info& rhs) const;
    int before(const type_info& rhs) const;
    virtual ~type_info();
  private:
    ......
};

typeid使用注意事項

Ⅰ typeid返回一個type_info對象的引用;

Ⅱ 如果想通過基類的指針獲得派生類的數據類型,基類必須帶有虛函數;

Ⅲ 只能獲取對象的實際類型。

3.操作符dynamic_cast

  • 允許運行時刻進行類型轉換,從而使程序能夠在一個類層次結構中安全地轉化類型。

dynamic_cast使用注意事項

Ⅰ 只能應用于指針和引用的轉換;

Ⅱ 要轉換的類型中必須包換虛函數;

Ⅲ 轉換成功返回派生類的地址,失敗返回NULL。

4.代碼示例

// 鳥類和飛機類都會“降落”和“起飛”,因此“降落”和“起飛”的特性寫入一個接口類中
// 鳥類會“覓食”,并繼承接口類的“降落”和“起飛”
// 飛機類會“負重”,并繼承接口類的“降落”和“起飛”
// 傳入一個基類指針,調用對象的“降落”和“起飛”。并根據對象的類型的不同,分別調用各自的“覓食”或“負重”
void doSomething(Flyable *obj) {
  obj->takeoff();
  
  cout << typeid(*obj).name() << endl;
  
  if(typeid(*obj) == typeid(Bird)) {
    Bird *bird = dynamic_cast<Bird *>(obj);
    bird->foraging();   // 如果是Bird,則覓食
  }
  
  if(typeid(*obj) == typeid(Plane)) {
    Plane *plane = dynamic_cast<Plane *>(obj);
    plane->carry(); // 如果是Plane,則負重
  }
  
  obj->land();
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,536評論 1 51
  • 上篇請看:C++編程思想重點筆記(上) 宏的好處與壞處 宏的好處:#與##的使用 三個有用的特征:字符串定義、字符...
    小敏紙閱讀 641評論 0 2
  • C++文件 例:從文件income. in中讀入收入直到文件結束,并將收入和稅金輸出到文件tax. out。 檢查...
    SeanC52111閱讀 2,848評論 0 3
  • 本文意在說明Android NDK 在實現C++ RTTI時的相關數據結構,并從匯編角度分析其內存布局,以幫助理解...
    f9dd77add98e閱讀 2,657評論 0 2
  • 放縱由心未守空明,浮華于你可曾煩亂。就像是你,似極了這天氣,淋淋種種著各種遇見。遇見一份欣喜,邂逅一場美夢。抑或悲...
    青春被忘路閱讀 180評論 0 1