仔細想想地位卑賤的類型轉換功能(cast),其在程序設計中的地位就象goto語句一樣令人鄙視。但是它還不是無法令人忍受,因為當在某些緊要的關頭,類型轉換還是必需的,這時它是一個必需品。
不過C風格的類型轉換并不代表所有的類型轉換功能。一來它們過于粗魯,能允許你在任何類型之間進行轉換。不過如果要進行更精確的類型轉換,這會是一個優(yōu)點。在這些類型轉換中存在著巨大的不同,例如把一個指向const對象的指針(pointer-to-const-object)轉換成指向非const對象的指針(pointer-to-non-const-object)(即一個僅僅去除cosnt的類型轉換),把一個指向基類的指針轉換成指向子類的指針(即完全改變對象類型)。傳統(tǒng)的C風格的類型轉換不對上述兩種轉換進行區(qū)分。(這一點也不令人驚訝,因為C風格的類型轉換是為C語言設計的,而不是為C++語言設計的)。
二來C風格的類型轉換在程序語句中難以識別。在語法上類型轉換由圓括號和標識符組成,而這些可以用在C++中的任何地方。這使得回答象這樣一個最基本的有關類型轉換的問題變得很困難,“在這個程序中是否使用了類型轉換?”。這是因為人工閱讀很可能忽略了類型轉換的語句,而利用象grep的工具程序也不能從語句構成上區(qū)分出它們來。
C++通過引進四個新的類型轉換操作符克服了C風格類型轉換的缺點,這四個操作符是,static_cast, const_cast, dynamic_cast, 和reintERPret_cast。在大多數(shù)情況下,對于這些操作符你只需要知道原來你習慣于這樣寫,(type) expression而現(xiàn)在你總應該這樣寫: static_cast(expression);例如,假設你想把一個int轉換成double,以便讓包含int類型變量的表達式產(chǎn)生出浮點數(shù)值的結果。如果用C風格的類型轉換,你能這樣寫:
int firstNumber, secondNumber;
...
double result = ((double)firstNumber)/secondNumber;
如果用上述新的類型轉換方法,你應該這樣寫:
double result = static_cast(firstNumber)/secondNumber;
這樣的類型轉換不論是對人工還是對程序都很容易識別。
static_cast 在功能上基本上與C風格的類型轉換一樣強大,含義也一樣。它也有功能上限制。例如,你不能用static_cast象用C風格的類型轉換一樣把struct轉換成int類型或者把double類型轉換成指針類型,另外,static_cast不能從表達式中去除const屬性,因為另一個新的類型轉換操作符const_cast有這樣的功能。
其它新的C++類型轉換操作符被用在需要更多限制的地方。const_cast 用于類型轉換掉表達式的const或volatileness屬性。通過使用const_cast,你向人們和編譯器強調(diào)你通過類型轉換想做的只是改變一些東西的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*類型變量的函數(shù)
update(const_cast(&csw));
// 正確,csw的const被顯示地轉換掉(
// csw和sw兩個變量值在update
//函數(shù)中能被更新)
update((SpecialWidget*)&csw);
// 同上,但用了一個更難識別
//的C風格的類型轉換
Widget *pw = new SpecialWidget;
update(pw); // 錯誤!pw的類型是Widget*,但是
// update函數(shù)處理的是SpecialWidget*類型
update(const_cast(pw));
// 錯誤!const_cast僅能被用在影響
// constness or volatileness的地方上。,
// 不能用在向繼承子類進行類型轉換。
到目前為止,const_cast最普通的用途就是轉換掉對象的const屬性。
不過C風格的類型轉換并不代表所有的類型轉換功能。一來它們過于粗魯,能允許你在任何類型之間進行轉換。不過如果要進行更精確的類型轉換,這會是一個優(yōu)點。在這些類型轉換中存在著巨大的不同,例如把一個指向const對象的指針(pointer-to-const-object)轉換成指向非const對象的指針(pointer-to-non-const-object)(即一個僅僅去除cosnt的類型轉換),把一個指向基類的指針轉換成指向子類的指針(即完全改變對象類型)。傳統(tǒng)的C風格的類型轉換不對上述兩種轉換進行區(qū)分。(這一點也不令人驚訝,因為C風格的類型轉換是為C語言設計的,而不是為C++語言設計的)。
二來C風格的類型轉換在程序語句中難以識別。在語法上類型轉換由圓括號和標識符組成,而這些可以用在C++中的任何地方。這使得回答象這樣一個最基本的有關類型轉換的問題變得很困難,“在這個程序中是否使用了類型轉換?”。這是因為人工閱讀很可能忽略了類型轉換的語句,而利用象grep的工具程序也不能從語句構成上區(qū)分出它們來。
C++通過引進四個新的類型轉換操作符克服了C風格類型轉換的缺點,這四個操作符是,static_cast, const_cast, dynamic_cast, 和reintERPret_cast。在大多數(shù)情況下,對于這些操作符你只需要知道原來你習慣于這樣寫,(type) expression而現(xiàn)在你總應該這樣寫: static_cast(expression);例如,假設你想把一個int轉換成double,以便讓包含int類型變量的表達式產(chǎn)生出浮點數(shù)值的結果。如果用C風格的類型轉換,你能這樣寫:
int firstNumber, secondNumber;
...
double result = ((double)firstNumber)/secondNumber;
如果用上述新的類型轉換方法,你應該這樣寫:
double result = static_cast(firstNumber)/secondNumber;
這樣的類型轉換不論是對人工還是對程序都很容易識別。
static_cast 在功能上基本上與C風格的類型轉換一樣強大,含義也一樣。它也有功能上限制。例如,你不能用static_cast象用C風格的類型轉換一樣把struct轉換成int類型或者把double類型轉換成指針類型,另外,static_cast不能從表達式中去除const屬性,因為另一個新的類型轉換操作符const_cast有這樣的功能。
其它新的C++類型轉換操作符被用在需要更多限制的地方。const_cast 用于類型轉換掉表達式的const或volatileness屬性。通過使用const_cast,你向人們和編譯器強調(diào)你通過類型轉換想做的只是改變一些東西的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*類型變量的函數(shù)
update(const_cast(&csw));
// 正確,csw的const被顯示地轉換掉(
// csw和sw兩個變量值在update
//函數(shù)中能被更新)
update((SpecialWidget*)&csw);
// 同上,但用了一個更難識別
//的C風格的類型轉換
Widget *pw = new SpecialWidget;
update(pw); // 錯誤!pw的類型是Widget*,但是
// update函數(shù)處理的是SpecialWidget*類型
update(const_cast(pw));
// 錯誤!const_cast僅能被用在影響
// constness or volatileness的地方上。,
// 不能用在向繼承子類進行類型轉換。
到目前為止,const_cast最普通的用途就是轉換掉對象的const屬性。

