在示例中使用static_cast很好,但reinterpret_cast不是。因爲reinterpret_cast不是轉換vtable。
不,問題是reinterpret_cast
完全遺忘了繼承。它將簡單地返回相同的地址。但static_cast
知道您正在執行向下轉換:即從基類轉換爲派生類。既然它知道這兩種類型,就相應地調整地址,即做正確的事情。
讓我們假裝我們實施勾畫出假想OVERLAPPEDEX
類,它具有這樣的虛函數:
+------+------------+------------------+-------------+
| vptr | OVERLAPPED | AssociatedClient | ClientState |
+------+------------+------------------+-------------+
^
|
ptr
指針我們給出指向OVERLAPPED
子對象。 reinterpret_cast
不會改變這一點。它只會改變類型。顯然,通過這個地址訪問OVERLAPPEDEX
類會很容易造成嚴重破壞,因爲它的子對象的位置現在都是錯誤的!
what we believe we have when we access OVERLAPPEDEX through the pointer
+------+------------+------------------+-------------+
| vptr | OVERLAPPED | AssociatedClient | ClientState |
+------+------+-----+------+-----------+------+------+------+
| vptr | OVERLAPPED | AssociatedClient | ClientState | <- what we actually have
+------+------------+------------------+-------------+
^
|
ptr
static_cast
知道,要轉換OVERLAPPED*
到OVERLAPPEDEX*
它必須調整的地址,並做正確的事:
+------+------------+------------------+-------------+
| vptr | OVERLAPPED | AssociatedClient | ClientState |
+------+------------+------------------+-------------+
^
|
ptr after static_cast
不過,如果我使用C-風格投在那裏(不是reinterpret_cast),它可能會出錯嗎?
A C樣式轉換被定義爲成功以下的第一個:
const_cast
static_cast
static_cast
,然後const_cast
reinterpret_cast
reinterpret_cast
,然後const_cast
正如你所看到的,static_cast
reinterpret_cast
之前嘗試過,所以在這種情況下,C樣式轉換也將做正確的事。
More info
不能保證。關於reinterpret_cast
發生的情況幾乎沒有什麼保證。我所知道的所有實現都將簡單地給出相同的地址。
我對C++一點也不熟悉,但我的理解是,「重新解釋強制轉換」意味着在C中'*(destination_type *)&'意味着什麼。推測「靜態強制轉換」實際上需要類關係帳戶,並允許編譯器進行非平凡的轉換工作。 – 2012-02-04 05:51:41