《More Effective C++》 Item M2:儘量使用C++風格的類型轉換

c++有四種類型轉換:static_cast、const_cast、dynamic_cast、reinterpret_cast

1.static_cast<type>(expression)

static_cast在功能上基本上與C風格的類型轉換一樣強大,含義也一樣。它也有功能上限制。例如,你不能用static_cast象用C風格的類型轉換一樣把struct轉換成int類型或者把double類型轉換成指針類型,另外,static_cast不能從表達式中去除const屬性
double result = static_cast<double>(firstNumber)/secondNumber;

2.const_cast

const_cast用於類型轉換掉表達式的const或volatileness屬性。通過使用const_cast,你向人們和編譯器強調你通過類型轉換想做的只是改變一些東西的constness或者 volatileness屬性。這個含義被編譯器所約束。如果你試圖使用const_cast來完成修改constness 或者volatileness屬性之外的事情,你的類型轉換將被拒絕。

class Widget { ... };
class SpecialWidget: public Widget { ... };
void update(SpecialWidget *psw);
SpecialWidget sw;                // sw 是一個非const 對象。
const SpecialWidget& csw = sw;   // csw 是sw的一個引用
                                // 它是一個const 對象 
update(&csw);  // 錯誤!不能傳遞一個const SpecialWidget* 變量
               // 給一個處理SpecialWidget*類型變量的函數 
update(const_cast<SpecialWidget*>(&csw));
			// 正確,csw的const被顯示地轉換掉(
			// csw和sw兩個變量值在update
			//函數中能被更新) 
update((SpecialWidget*)&csw);
                         // 同上,但用了一個更難識別
                         //的C風格的類型轉換
Widget *pw = new SpecialWidget; 
update(pw);         // 錯誤!pw的類型是Widget*,但是
                    // update函數處理的是SpecialWidget*類型 
update(const_cast<SpecialWidget*>(pw));
                    // 錯誤!const_cast僅能被用在影響
                    // constness or volatileness的地方上。,
                    // 不能用在向繼承子類進行類型轉換。

3. dynamic_cast

它被用於安全地沿着類的繼承關係向下進行類型轉換。這就是說,你能用dynamic_cast把指向基類的指針或引用轉換成指向其派生類或其兄弟類的指針或引用,而且你能知道轉換是否成功。失敗的轉換將返回空指針(當對指針進行類型轉換時)或者拋出異常(當對引用進行類型轉換時)

Widget *pw;
...
update(dynamic_cast<SpecialWidget*>(pw));
			// 正確,傳遞給update函數一個指針
			// 是指向變量類型爲SpecialWidget的pw的指針
			// 如果pw確實指向一個對象,
			// 否則傳遞過去的將使空指針。
void updateViaRef(SpecialWidget& rsw);
updateViaRef(dynamic_cast<SpecialWidget&>(*pw));
                         //正確。 傳遞給updateViaRef函數
                         // SpecialWidget pw 指針,如果pw 
                         // 確實指向了某個對象
                         // 否則將拋出異常
dynamic_casts在幫助你瀏覽繼承層次上是有限制的。它不能被用於缺乏虛函數的類型上(參見條款M24),也不能用它來轉換掉constness:
int firstNumber, secondNumber;
...
double result = dynamic_cast<double>(firstNumber)/secondNumber;
                         // 錯誤!沒有繼承關係
const SpecialWidget sw;
...
update(dynamic_cast<SpecialWidget*>(&sw));
                         // 錯誤! dynamic_cast不能轉換
                         // 掉const。

4. reinterpret_cast

reinterpret_casts的最普通的用途就是在函數指針類型之間進行轉換

typedef void (*FuncPtr)();      // FuncPtr is 一個指向函數
                                // 的指針,該函數沒有參數
				// 返回值類型爲void
FuncPtr funcPtrArray[10];       // funcPtrArray 是一個能容納
                                // 10個FuncPtrs指針的數組


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章