| 運算子 | 用途 | 執行期檢查 |
|---|---|---|
static_cast | 編譯期已知的相關類型轉換 (如基礎型別、類別層級向上/向下) | 無 |
dynamic_cast | 多態類別層級的**安全向下轉型** | **有** (需 RTTI) |
const_cast | 移除/添加 const/volatile | 無 |
reinterpret_cast | 底層位元模式重新解讀 (極度危險) | 無 |
nullptr,參考拋出 std::bad_cast 例外。class Base { public: virtual ~Base() {} int m_iNum; };
class Derived : public Base { public: char* m_szName; };
int main() {
Base* pb = new Derived("abc"); // 基類指標指向衍生物件
// 1. 正確向下轉型:衍生 -> 基類指標實際指向衍生物件
Derived* pd1 = static_cast(pb); // 編譯期信任,無檢查
Derived* pd2 = dynamic_cast(pb); // 執行期檢查,安全
// 兩者皆可正常存取 pd->m_szName
// 2. 危險向下轉型:基類指標指向基類物件
Base* pb2 = new Base();
Derived* pd3 = static_cast(pb2); // 編譯通過,執行期未定義行為 (存取 m_szName 會崩潰)
Derived* pd4 = dynamic_cast(pb2); // 回傳 nullptr,安全失敗
cout << pd3 << endl; // 非零位址 (假象)
cout << pd4 << endl; // 0 (nullptr)
}
cout << sizeof(Base) << endl; // 16 (vptr 8 + int 4 + padding 4) cout << sizeof(Derived) << endl; // 24 (Base 16 + char* 8) cout << sizeof(*pb) << endl; // 16 (靜態類型 Base*,只知 Base 大小)
注意:sizeof(*pb) 看的是靜態類型 Base 的大小,而非動態類型 Derived。
dynamic_cast 需走 RTTI 機制,遍歷繼承圖檢查類型關係,比 static_cast 慢。在效能敏感熱路徑,若能確保型別正確,優先用 static_cast;否則寧可犧牲效能換取安全。
dynamic_cast 並檢查回傳值。-fno-rtti) 會導致 dynamic_cast 編譯失效。