這是Effective C++中第27個原則,作者花了很長的篇幅來介紹這一原則梧税。
總而言之一句話,因?yàn)轭愋娃D(zhuǎn)換會導(dǎo)致破壞類型系統(tǒng)称近,從而帶來明顯的和不明顯麻煩第队,而且這是C++獨(dú)有的特性。
C++提供了四種新型的類型轉(zhuǎn)換煌茬,就是下面這四種:
const_cast是把const類型轉(zhuǎn)換成非const類型斥铺;
dynamic_cast是類體系中進(jìn)行轉(zhuǎn)換;
reinterpret_cast是一個很強(qiáng)大的類型轉(zhuǎn)換坛善,最常用的是指針轉(zhuǎn)換為指針晾蜘,而且是兩個毫不相關(guān)的指針之間的轉(zhuǎn)換邻眷,它傳遞的是比特位。換句話說這些比特位是不變的剔交,但是它能按照另一種方式來解釋它肆饶。
static_cast就是平常的類型轉(zhuǎn)換,用的最廣泛岖常。
須知驯镊,在C++中,類型轉(zhuǎn)換往往能夠令編譯器編譯出運(yùn)行時代碼竭鞍,可想而知板惑,這個代碼并不是你寫的。在這里作者舉了一個多態(tài)的例子偎快,當(dāng)你用父類的指針指向子類的對象時冯乘,父類的指針指向的地址和子類對象所在的地址并不是一個,它倆之間有時候是有個偏移量的晒夹。
作者又舉了一個例子●陕現(xiàn)有一父類和其子類,兩類有兩個同名的虛函數(shù)丐怯,現(xiàn)要求子類虛函數(shù)中首先調(diào)用父類虛函數(shù)喷好,這是子類虛函數(shù)的代碼是這樣子的。
通過子類的this指針強(qiáng)制類型轉(zhuǎn)換成父類類型读跷,然后調(diào)用同名函數(shù)梗搅。但是次轉(zhuǎn)換的過程并不是你所想象的那樣簡單,這個強(qiáng)制類型轉(zhuǎn)換會創(chuàng)造出一個被轉(zhuǎn)型對象的副本舔亭,它是在這個副本身上執(zhí)行父類的同名函數(shù)些膨,而在該對象身上執(zhí)行本類專屬的同名函數(shù),兩者本應(yīng)作用于同一個對象而實(shí)際上卻沒有钦铺。而解決這個問題的辦法就是不用強(qiáng)制類型轉(zhuǎn)換订雾,你該用父類的成員函數(shù)就用就行了。
而dynamic_cast這個轉(zhuǎn)換你最好不要用矛洞,因?yàn)樗莿討B(tài)轉(zhuǎn)換洼哎,它會在整個類層次上進(jìn)行尋找,而且每轉(zhuǎn)換一次就尋找一次沼本,并且它是按照類名進(jìn)行字符串匹配的噩峦。
通常你使用dynamic_cast進(jìn)行強(qiáng)制類型轉(zhuǎn)換的情景是用一個父類的指針指向子類對象,這種情況你應(yīng)該使用的是子類類型的只能指針抽兆,作者使用的是一個裝有智能指針的vector识补。如果子類很多,并且你非要用父類類型的話辫红,那你可以在父類中提供一個同名空虛函數(shù)凭涂,并在各個子類中去實(shí)現(xiàn)它祝辣,然后你再用vector去容納裝有父類類型的智能指針,然后去操作切油。為啥要使用vector呢蝙斜?因?yàn)樗穷愋桶踩萜鳌?br> 在這里一定要記住不要在程序中多次使用dynamic_cast做沒有必要的類型轉(zhuǎn)換,因?yàn)檫@樣做不僅代碼多澎胡,而且運(yùn)行慢孕荠,因?yàn)閐ynamic_cast需要查找嘛。
最后作者衷心地告訴大家盡量不要使用強(qiáng)制類型轉(zhuǎn)換攻谁,尤其是除static_cast之外的另外三種稚伍;強(qiáng)制類型轉(zhuǎn)換如果必要,那也要把它包裹在一個函數(shù)里面巢株,不要讓用戶接觸到槐瑞;推薦使用C++強(qiáng)制類型轉(zhuǎn)換,它不僅容易分辨阁苞,而且各司其職。