C++的幾種強制類型轉換


  有時我們希望顯式地將對象強制類型轉換成另外一種類型。例如,如果想在下面的代碼中執行浮點數除法:

  int i, j;

  double slope = i / j;

  就要使用某種方法將i和/或j顯式地轉換成double,這種方法稱作強制類型轉換。

 

命名的強制類型轉換

  一個命名的強制類型轉換具有如下形式:

  cast_name<type>(expression);

  其中,type是轉換的目標類型而expression是要轉換的值。如果type是引用類型,則結果是左值,cast-name是static_cast, dynamic_cast, const_cast和reinterpret_cast中的一種。dynamic_cast支持運行時類型識別。cast-name指定了執行的是哪種轉換。

 

static_cast

  任何具有明確定義的類型轉換,只要不包含底層const,都可以使用static_const。

  例如,通過將一個運算對象強制轉換成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異常 .


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM