有時咱們但願顯式地將對象強制類型轉換成另一種類型。例如,若是想在下面的代碼中執行浮點數除法:express
int i, j;spa
double slope = i / j;指針
就要使用某種方法將i和/或j顯式地轉換成double,這種方法稱做強制類型轉換。code
命名的強制類型轉換對象
一個命名的強制類型轉換具備以下形式:blog
cast_name<type>(expression);ip
其中,type是轉換的目標類型而expression是要轉換的值。若是type是引用類型,則結果是左值,cast-name是static_cast, dynamic_cast, const_cast和reinterpret_cast中的一種。dynamic_cast支持運行時類型識別。cast-name指定了執行的是哪一種轉換。字符串
static_cast編譯器
任何具備明肯定義的類型轉換,只要不包含底層const,均可以使用static_const。string
例如,經過將一個運算對象強制轉換成double類型就能使表達式執行浮點數除法:
double slope = static_cast<double>(j) / i;
當須要把一個較大的算術類型賦值給較小的類型時,static_cast很是有用。此時,強制類型轉換告訴程序的讀者和編譯器:咱們知道而且不在意潛在的精度損失。通常來講,若是編譯器發現一個的算術類型試圖賦值給較小的類型,就會給出警告信息;可是當咱們執行了顯式的類型轉換後,警告信息就會被關閉了。
static_cast對於編譯器沒法自動執行的類型轉換也很是有用。例如,咱們可使用static_cast找回存在於void*指針中的值:
void *p = &d; //正確:任何很是量對象的地址都能存入void*
//正確:將void*轉換回初始的指針類型
double *dp = static_cast<double*>(p);
當咱們把指針存放在void*中,而且使用static_cast將其強制轉換回原來的類型時,應該確保指針的值保持不變。也就是說,強制轉換的結果將與原始的地址值相等,所以咱們必須確保轉換後所得的類型就是指針所指的類型。類型一旦不符,將產生未定義的後果。
const_cast
const_cast只能改變運算對象的底層const
const char *pc;
char *p = const_cast<char*> (pc); //正確:可是經過p寫值是未定義的行爲
對於將常量對象轉化爲很是量對象的行爲,咱們通常稱之爲」去掉const性質(cast away the const)「。一旦咱們去掉了某個對象的const性質,編譯器就再也不阻止咱們對該對象進行寫操做了。若是對象自己不是一個常量,使用強制類型轉換得到寫權限是合法的行爲。然而若是對象是一個常量,再使用const_cast執行寫操做就會產生未定義的後果。
只有 const_cast能改變表達式的常量屬性,使用其餘形式的命名強制類型轉換改變表達式的常量屬性都將引起編譯器錯誤。一樣地,也不能用const_cast改變表達式的類型:
const char *cp; //錯誤:static_cast不能轉換掉const性質 char* q = static_cast<char*> (cp); static_cast<string> (cp); //正確,字符串字面值轉換成string類型 const_cast<string>(cp); //錯誤,const_cast只改變常量屬性
總結來講:const_cast只能改變底層const,即它只能改變對象或引用的const屬性,不能改變對象的const屬性。const_cast便可以添加const性質,也能夠刪除const性質。
reinterpret_cast
reinterpret_cast一般爲運算對象的位模式提供較低層次上的從新解釋。舉個例子,假設有以下的轉換:
int *ip;
char *pc = reinterpret_cast<char*>(ip);
咱們必須牢記pc所指的真實對象是int而非字符,若是把pc當成一個普通的字符指針使用就可能在運行時發生錯誤。例如:
string str(po);
可能致使異常的運行時行爲。
使用reinterpret_cast是很是危險的,用pc初始化的例子很好地證實了這一點。其中的關鍵問題是類型改變了,但編譯器沒有給出任何警告或者錯誤的提示信息。當咱們用一個int的地址初始化pc時,因爲顯式地聲稱這種轉換合法,因此編譯器不會發出任何警告或錯誤信息。接下來再使用pc時就會認定它的值是char*類型,編譯器無法知道它實際存放的是指向int的指針。
dynamic_cast
只用於對象的指針和引用. 當用於多態類型時,它容許任意的隱式類型轉換以及相 反過程. 不過,與static_cast不一樣,在後一種狀況裏(注:即隱式轉換的相反過程),dynamic_cast 會檢查操做是否有效. 也就是說, 它會檢查轉換是否會返回一個被請求的有效的完整對象。檢測在運行時進行. 若是被轉換的指針不是一個被請求的有效完整的對象指針,返回值爲NULL. 對於引用 類型,會拋出bad_cast異常 .