標籤

C++ (12) Linux (6) MacOSX (4) Makefile (3) Matlab (3) Ubuntu (3) Android (2) C (1) Refactoring (1)

2012年4月7日 星期六

[C++] 各式各樣的CAST

如果你對static_cast, dynamic_cast 等等還不甚熟悉
那你一定不常使用多型 (polymorphism)
更別說你懂物件導向語言

今天要講的主題是cast運算子 (operator)
包括了static_cast, const_cast, dynamic_cast, reinterpret_cast這四個運算子

這裡我就擷取一些精華翻譯一下:

static_cast

當你要cast時,你應該要優先嘗試使用static_cast。簡單來說,它提供安全的型態轉換,不論是double轉int,或是繼承 (inheritance) 中的垂直轉換,例如把Derived*轉成Base*(當然向上轉換也可以不使用任何cast)或是把Base*轉成Derived*。要注意的是static_cast沒辦法在虛擬繼承 (virtual inheritance) 中轉換,也不適用於將裝在Base*裡的Base物件向下轉至Derived*(會造成undefined behavior)

例子:double a = static_cast(b), Derived* dp = static_cast(bp), 等等


const_cast

這部份我就不在此贅述。有興趣的自己隨便google就有一堆了。


dynamic_cast

這是專門用來處理多型架構的類別。可以向上向下轉,你想怎麼轉就怎麼轉,轉pointer轉不過去時就會得到NULL,而reference轉不過去時,dynamic_cast會丟出 (throw) std::bad_cast,請記得好好接住。但強大的dynamic_cast也是有它的限制,像是dreaded diamond、protected/private inheritance等等鮮少出用的情況,前者的話用virtual inheritance或是範圍運算子(::)可以搞定,有後者情況的話,我只能說你太強了,這裡應該不是你會來的地方。


reinterpret_cast

這是最危險也最不該被使用的cast。最危險的意思是不當使用這種cast,可能會造成難以排除的BUG,例如寫了一行(reinterpret_cast(ptr))->foo(),結果程式跑起來時卻執行別的函式例如whatthe(int x, vector& v)之類這種完全搭不上邊,參數型數量型態和回傳值都不同的函式。reinterpret_cast唯一提供的保證是:轉過去再轉回來後完全不會改變該物件的內容(也就是它被叫做reinterpret


如果想要對多重繼承以及記憶體使用狀況有更深入的瞭解
可以參考下面這篇:Virtual Methods and Multiple Inheritance
以上拉哩拉匝的供大家參考,希望多少有點幫助。
有任何疑問或錯誤儘管提出。

沒有留言:

張貼留言