首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

從 RTTI 機制深入理解 C++ 向下轉型與動態類型識別

     編輯:關於C語言

什麼是 RTTI?

RTTI(Run-Time Type Information,執行期類型資訊) 讓程式在執行期間能辨識物件的實際衍生類型。C++ 提供兩大核心運算子:

  • dynamic_cast:執行期安全向下轉型,失敗回傳 nullptr(指標)或拋出異常(引用)。
  • typeid:回傳 std::type_info 參考,可比較類型名稱與繼承關係。

前提條件:類別必須包含至少一個 virtual 函數(多態類別),否則 RTTI 僅在編譯期生效。

RTTI 底層實作原理

C++ 編譯器為每個多態類別建立 type_info 物件,儲存類別名稱、繼承關係等。虛函數表(vtable)的第一個槽位通常存放指向該 type_info 的指標。透過物件的 vptr 即可在執行期取得類型資訊:

type_info& info = *static_cast(obj->vptr)[0];

這也是為何只有多態類別(有虛函數)才支援 RTTI——非多態類別沒有 vtable,無法存放型別資訊。

向下轉型詳細分類

將基類指標/引用轉為衍生類指標/引用稱為「向下轉型」。注意:無法直接將基類物件轉為衍生類物件(會造成物件切割),只能轉換指標或引用。

三種轉型方式比較

方式語法安全性條件
C 風格轉型(Derived*)basePtr不安全,無檢查任意類別
static_caststatic_cast(basePtr)不安全,無執行期檢查任意類別
dynamic_castdynamic_cast(basePtr)安全,執行期檢查基類需有虛函數

程式碼範例

class Base { virtual void foo() {} };
class Derived : public Base { int extra; };

Base* pb = new Base;
Derived* pd1 = static_cast(pb);  // 編譯通過,執行危險
Derived* pd2 = dynamic_cast(pb); // 回傳 nullptr,安全

Base* pb2 = new Derived;
Derived* pd3 = dynamic_cast(pb2); // 成功,指向完整 Derived

向下轉型的潛在風險

若基類指標實際指向基類物件,強制轉為衍生類指標並存取衍生類專有成員(如 extra),會導致記憶體越界、未定義行為。dynamic_cast 能在執行期偵測此情況並回傳 nullptr,是唯一安全的向下轉型方式。

交叉轉型

dynamic_cast 還支援「交叉轉型」(Cross Cast):在同一繼承體系的不同分支間轉型。static_cast 會編譯錯誤,而 dynamic_cast 回傳 nullptr 表示失敗。

總結

  • RTTI 需虛函數支援,依賴 vtable 儲存 type_info。
  • dynamic_cast 是唯一具備執行期類型檢查的向下轉型工具。
  • 濫用向下轉型通常暗示設計缺陷,優先考慮虛函數多態或 Visitor 模式。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved