static_cast
如何工作?如果你正在做的事情一樣......static_cast是如何在C++中實現的?
如果d通過一些未指定的層次結構(不一定直接)的B繼承,你這樣做:
B* b = new D();
D* d = static_cast<D*>(b);
發生了什麼?它只是在編譯時計算偏移量並將該偏移量應用於指針?或者在運行時發生了什麼事情以便執行演員?
static_cast
如何工作?如果你正在做的事情一樣......static_cast是如何在C++中實現的?
如果d通過一些未指定的層次結構(不一定直接)的B繼承,你這樣做:
B* b = new D();
D* d = static_cast<D*>(b);
發生了什麼?它只是在編譯時計算偏移量並將該偏移量應用於指針?或者在運行時發生了什麼事情以便執行演員?
發生了什麼事?
編譯器假定你知道你在做什麼,使指針確實指向一個對象D
,並相應地改變指針類型,調整值,如果有必要指向完整D
對象,而比B
子對象。
如果你弄錯了,並且使用一個D*
指針,它並不指向D
對象,那麼你會得到未定義的行爲;所以要小心。
它只是在編譯時計算偏移量並將該偏移量應用於指針?
是。
或者是否有什麼事發生在運行時爲了做演員?
否; 「靜態」意味着它僅使用編譯時信息。唯一的運行時活動是在必要時添加固定偏移量。
如果您想運行時檢查轉換是否有效(只要類型是多態),則使用dynamic_cast
。如果沒有真正的D
對象,它會給出一個空指針(或者拋出一個bad_cast
異常,如果你正在投射引用而不是指針)。
要在這裏得到一個完整的答案,你可以通過簡單地寫'D * d =((D *)b);來解釋這兩者的區別來完成答案。 – Emadpres 2014-12-09 16:33:09
@Emadpres:在這種情況下,C風格的演員陣容與「static_cast」完全相同;不同之處在於,在'static_cast'失敗的情況下,它可以回退到更可疑的轉換。但問題是關於'static_cast'的具體問題,所以這不是特別相關。 – 2014-12-09 16:35:21
'static_cast'總是使用編譯時類型信息來解析。 (這可能涉及運行時操作)。如果這不是一個合適的強制轉換,你會得到一個編譯錯誤或未定義的行爲。在你的代碼片段中,它是可以的,因爲'b'是'D';但是如果'b'是'new B()',那麼cast會編譯,但如果運行則會導致未定義的行爲。 – 2014-12-09 11:57:12
是的,它只是在編譯時計算偏移量並添加它。除非有多個和/或虛擬繼承正在進行(或者您有一個非常奇怪的編譯器),否則偏移量將爲0,因此實際上不會發出額外的代碼。 – 2014-12-09 12:10:28