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

C++ 四大強制類型轉換與 RTTI 深度解析:static_cast、dynamic_cast、const_cast、reinterpret_cast

     編輯:C++ 入門

統一語法形式

cast_name<type>(expression),其中 cast_name 為四種關鍵字之一,type 為目標類型,expression 為待轉換值。

1. static_cast:編譯期靜態轉換

適用場景:

  • 內置類型轉換(int → double、int → enum 等)
  • 類層次結構中上行轉換(派生類指針/引用 → 基類指針/引用),安全
  • 類層次結構中下行轉換(基類指針/引用 → 派生類指針/引用),無運行時檢查,不安全
  • void* 通用指針轉回原類型指針
  • 任意表達式轉 void 類型(丟棄值)

限制:不能移除 const/volatile/__unaligned 屬性。

2. const_cast:修改常量屬性

唯一用途:增加或移除底層 const/volatile 資格,不改變類型。其他任何 cast 均不能修改常量性。

const char *pc = "hello";
char *p = const_cast<char*>(pc);  // 合法,但通過 p 寫入行為未定義
// char *q = static_cast<char*>(pc); // 編譯錯誤

典型應用:函數重載中避免代碼重複——非常量版調用常量版,再用 const_cast 移除返回值的 const。

3. reinterpret_cast:底層位模式重新解釋

極度危險:僅重新解釋位模式,不做任何類型檢查。典型用法:指針類型間強制轉換(int* → char*)、指針與整數互轉。

int *ip = new int(42);
char *pc = reinterpret_cast<char*>(ip);  // pc 指向 int 的第一個字節
// string str(pc); // 錯誤:pc 非真正的 C 風格字符串

原則:除非極度必要(如硬件編程、序列化),否則盡量避免使用。

4. dynamic_cast:運行時類型安全轉換(RTTI 核心)

前提:目標類型必須為多態類型(至少有一個虛函數)。

三種形式:

  • dynamic_cast<T*>(p):失敗返回 nullptr
  • dynamic_cast<T&>(ref):失敗拋出 bad_cast 異常
  • dynamic_cast<T&&>(expr):C++11 右值引用,失敗拋出異常

合法轉換條件(e 為源表達式,T 為目標類型):

  1. e 是 T 的公有派生類
  2. e 是 T 的公有基類
  3. e 類型即為 T

dynamic_cast vs static_cast 關鍵差異

場景static_castdynamic_cast
上行轉換安全,編譯期完成安全,運行時檢查(開銷略大)
下行轉換(指針真指向派生對象)編譯通過,運行時未定義行為風險安全,返回正確指針
下行轉換(指針實為基類對象)編譯通過,運行時崩潰/邏輯錯誤返回 nullptr,可捕獲
交叉轉換(多重繼承/無關類)編譯錯誤允許,失敗返回 nullptr

typeid 運算符

  • typeid(e) 返回 const type_info&,可比較類型相等、獲取類型名稱
  • 非多態類型/非引用表達式 → 靜態類型(編譯期確定)
  • 多態類型的左值(引用/解引用指針) → 動態類型(運行期確定,需虛函數表)
  • typeid(*p) 若 p 為空指針且類型多態 → 拋出 bad_typeid

性能與設計建議

  1. dynamic_cast 實現常基於字符串比較類名,深層繼承/多重繼承開銷大
  2. 優先使用虛函數實現多態,避免強制轉換
  3. 若必須轉換,封裝在函數內部,暴露安全接口
  4. 無繼承關係/無虛函數類型間轉換 → 編譯錯誤,這正是類型安全的體現

掌握四大 cast 的適用邊界與 dynamic_cast/typeid 的 RTTI 機制,是編寫健壯、可維護 C++ 代碼的關鍵技能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved