2014-12-09 68 views
1

static_cast如何工作?如果你正在做的事情一樣......static_cast是如何在C++中實現的?

如果d通過一些未指定的層次結構(不一定直接)的B繼承,你這樣做:

B* b = new D(); 
D* d = static_cast<D*>(b); 

發生了什麼?它只是在編譯時計算偏移量並將該偏移量應用於指針?或者在運行時發生了什麼事情以便執行演員?

+4

'static_cast'總是使用編譯時類型信息來解析。 (這可能涉及運行時操作)。如果這不是一個合適的強制轉換,你會得到一個編譯錯誤或未定義的行爲。在你的代碼片段中,它是可以的,因爲'b'是'D';但是如果'b'是'new B()',那麼cast會編譯,但如果運行則會導致未定義的行爲。 – 2014-12-09 11:57:12

+2

是的,它只是在編譯時計算偏移量並添加它。除非有多個和/或虛擬繼承正在進行(或者您有一個非常奇怪的編譯器),否則偏移量將爲0,因此實際上不會發出額外的代碼。 – 2014-12-09 12:10:28

回答

4

發生了什麼事?

編譯器假定你知道你在做什麼,使指針確實指向一個對象D,並相應地改變指針類型,調整值,如果有必要指向完整D對象,而比B子對象。

如果你弄錯了,並且使用一個D*指針,它並不指向D對象,那麼你會得到未定義的行爲;所以要小心。

它只是在編譯時計算偏移量並將該偏移量應用於指針?

是。

或者是否有什麼事發生在運行時爲了做演員?

否; 「靜態」意味着它僅使用編譯時信息。唯一的運行時活動是在必要時添加固定偏移量。

如果您想運行時檢查轉換是否有效(只要類型是多態),則使用dynamic_cast。如果沒有真正的D對象,它會給出一個空指針(或者拋出一個bad_cast異常,如果你正在投射引用而不是指針)。

+0

要在這裏得到一個完整的答案,你可以通過簡單地寫'D * d =((D *)b);來解釋這兩者的區別來完成答案。 – Emadpres 2014-12-09 16:33:09

+0

@Emadpres:在這種情況下,C風格的演員陣容與「static_cast」完全相同;不同之處在於,在'static_cast'失敗的情況下,它可以回退到更可疑的轉換。但問題是關於'static_cast'的具體問題,所以這不是特別相關。 – 2014-12-09 16:35:21