C 風格強制轉型 (Type)expr 功能過於強大且難搜尋。C++ 提供四種具體語義的轉型運算子,讓意圖明確、編譯器可檢查、易於維護。
void* 還原)。const/volatile、無關類別指標互轉。
class B { ... };
class D : public B { ... };
void f(B* pb, D* pd) {
D* pd2 = static_cast<D*>(pb); // 不安全:pb 可能僅指向 B
B* pb2 = static_cast<B*>(pd); // 安全:派生類指標隱式轉基類
}
nullptr(指標版)或拋出 bad_cast(引用版)。
class A { virtual ~A() {} };
class B { virtual ~B() {} };
void f() {
A* pa = new A;
B* pb = new B;
void* pv = dynamic_cast<A*>(pa); // ok,pv 指向 A
pv = dynamic_cast<B*>(pb); // ok,pv 指向 B
D* pd = dynamic_cast<D*>(pa); // nullptr,A 非 D 基類
}
const 或 volatile 資格,**型別其餘部分必須完全相同**。const(如存放在唯讀記憶體),透過結果修改行為未定義。const 正確的舊式 API。
class A { ... };
void legacy_api(A* p); // 老介面無 const
void f() {
const A* pa = new A;
// A* pb = pa; // 錯誤:const 不能隱式轉非 const
A* pb = const_cast<A*>(pa); // 編譯通過,但若 legacy_api 修改 pb → UB
legacy_api(pb);
}
reinterpret_cast<T*>(reinterpret_cast<U*>(p)) == p),其他行為平台相關。
class A { ... };
class B { ... };
void f() {
A* pa = new A;
B* pb = reinterpret_cast<B*>(pa); // 極度不安全:A、B 佈局可能完全不同
int addr = reinterpret_cast<int>(pa); // 指標轉整數(平台相關)
}
| 場景 | 推薦運算子 |
|---|---|
| 數值型別轉換、上行轉型、void* 還原 | static_cast |
| 多態下行轉型、交叉轉型 | dynamic_cast |
| 去除 const/volatile(對接舊 API) | const_cast |
| 底層位元重解釋、指標整數互轉 | reinterpret_cast |
static_cast,其次 dynamic_cast,最後才 reinterpret_cast。reinterpret_cast/const_cast 封裝在薄介面層,核心邏輯保持型別安全。掌握四大轉型運算子的語義邊界,是寫出健壯、可維護 C++ 代碼的關鍵技能。