Effective C++ 第二十七條 Minimize casting.
盡量少做轉(zhuǎn)型動(dòng)作
C++的設(shè)計(jì)目標(biāo)之一就是保證“類(lèi)型錯(cuò)誤”絕不可能發(fā)生。但是 cast 破壞了類(lèi)型系統(tǒng)。
C++ 中有新舊兩種轉(zhuǎn)換方式:
舊式:
(T) expression
T(expression)
這兩種就是將 expression 轉(zhuǎn)為 T 類(lèi)型
新式:
const_cast 將對(duì)象的常量性去除,也就是 const → non-const
dynamic_cast 用于 base 和 derived 之間的轉(zhuǎn)換,主要執(zhí)行 “安全向下轉(zhuǎn)型”,向上轉(zhuǎn)換總是成功且安全,向下轉(zhuǎn)換不都是成功的,對(duì)于指針如果不成功返回空指針,對(duì)于引用如果不成功拋出異常。
reinterpret_cast 不會(huì)變成任何機(jī)器指令,也就是沒(méi)有真正轉(zhuǎn)換,只是告訴編譯器要將數(shù)據(jù)當(dāng)作什么類(lèi)型來(lái)處理而不真正轉(zhuǎn)換為該類(lèi)型。不能用來(lái)處理 cv 類(lèi)型。
static_cast 用來(lái)強(qiáng)迫隱式轉(zhuǎn)換,將 non-const 轉(zhuǎn)換為 const,int轉(zhuǎn)換為double,但不能將 const 轉(zhuǎn)換為 non-const。
C++ 的轉(zhuǎn)換不同于 C、java等,C++的轉(zhuǎn)換可能會(huì)導(dǎo)致指針的值改變,一個(gè) Derived 對(duì)象 d,base指針指向 d 的時(shí)候有一個(gè)地址,derived 類(lèi)型的指針指向 d 的時(shí)候又有一個(gè)地址,而且兩個(gè)地址可以不相同。一旦設(shè)計(jì)多重繼承,指針類(lèi)型轉(zhuǎn)換就有可能出錯(cuò)。由于地址的計(jì)算方式隨著編譯器不同而不同,在這個(gè)平臺(tái)這樣算行得通,換個(gè)平臺(tái)也許就不行了。
我們?cè)?derived 中執(zhí)行 virtual 函數(shù)的時(shí)候首先調(diào)用 base 中改函數(shù)
這段代碼就隱藏了一下易錯(cuò)點(diǎn),如我們預(yù)期那樣,*this (derived) 被轉(zhuǎn)換為了 base,但是如果 fun 涉及到成員變量修改,那么就會(huì)引發(fā)歧義。*this 變成了 base 類(lèi)型,但是代碼中 fun 不是 this 調(diào)用的,而是 static_cast<base>(*this) 返回的一個(gè)臨時(shí)變量執(zhí)行的 fun,也就是說(shuō)如果 fun 涉及成員變量修改,對(duì) this 沒(méi)有任何影響。而 static_cast 之后的語(yǔ)句又是對(duì) this 進(jìn)行操作的。
dynamic_cast 是處理以下情況,你想調(diào)用 derived 的函數(shù),但你只有且只能使用一個(gè) base 指針。你可以這樣做
千萬(wàn)不要使用第一種,dynamic開(kāi)銷(xiāo)很大,使用 type 2 更為安全和高效。
絕對(duì)要避免的就是使用“連串”的 dynamic_cast,比如這樣

總結(jié):
盡量避免轉(zhuǎn)型,在注意效率的代碼中避免 dynamic_cast
如果轉(zhuǎn)型是必要的,最好隱藏在某個(gè)函數(shù)后面,而不用顯示寫(xiě)出來(lái)
使用新型轉(zhuǎn)型,不要使用舊型,新型容易被分辨,出錯(cuò)也容易定位