使用 dynamic_cast 進行向上/向下轉換時,編譯器自動調整指針位置以指向正確的子對象:
C051 obj;
C041 * pt1 = dynamic_cast<C041*>(&obj); // 無調整
C042 * pt2 = dynamic_cast<C042*>(&obj); // 需調整至第二個 vptr
匯編顯示 pt2 賦值涉及:檢查源指針非空 → 讀取偏移值指針 → 計算新地址。而普通指針賦值僅兩條指令。動態轉換保證多態語義正確,但有運行期開銷。
C082 c082;
C041 temp = (C041)c082; // 編譯器生成臨時 C041 對象
輸出證明:
C041 虛表,而非 C082 的虛表。c_)被複製到臨時對象。原因:對象轉換不需保持多態,編譯器寧可創建新對象並複製數據,也不修改虛表條目(太複雜)。
((C041)c082).somefun(); // 若 somefun 修改狀態,僅影響臨時對象,原對象不變
正確做法:obj.C010::foo(); 顯式調用基類版本,作用於原對象。
若基類構造函數為 protected,向上轉型創建臨時對象會導致編譯錯誤(無法構造基類)。
| 轉換類型 | 指針動態轉換 | 對象強制轉換 |
|---|---|---|
| 機制 | 調整指針位置 | 創建臨時對象並複製數據 |
| 多態性 | 保持 | 丟失(切片) |
| 開銷 | 指針運算 | 構造/析構 + 複製 |
| 安全性 | dynamic_cast 可檢查 | 無檢查,隱式切片 |