c語言中的強制型別轉換(type cast)有顯式和隱式兩種,顯式一般就是直接用小括號強制轉換,type b = (type)a; 隱式就是直接 float b = 0.5; int a = b; 這樣隱式截斷(by the way 這樣隱式的截斷是向 0 取整的,我喜歡這麼叫因為 0.9 會變成 0,1.9 變成 1,-0.9 變成 0,-1.9 變成 -1)。
c++對c相容,所以上述方式的型別轉換是可以的,但是有時候會有問題,所以推薦使用c++中的四個強制型別轉換的關鍵字:
1、static_cast,2、const_cast,3、reinterpret_cast,4、dynamic_cast
這應該四種中是最常見的。用法為static_cast(expression)
。
該運算子把expression
轉換為type-id
型別,但沒有執行時型別檢查來保證轉換的安全性。
主要用法如下:
(1)用於類層次結構中基類(父類)和派生類(子類)之間指標或引用的轉換。
進行上行轉換(把派生類的指標或引用轉換成基類表示)是安全的;
進行下行轉換(把基類指標或引用轉換成派生類表示)時,由於沒有動態型別檢查,所以是不安全的。
(2)用於基本資料型別之間的轉換,如把int轉換成char,把int轉換成enum。這種轉換的安全性也要開發人員來保證。
(3)把空指標轉換成目標型別的空指標。
(4)把任何型別的表示式轉換成void型別。
最常用的應該還是基本資料型別之間的轉換,如下:
const
auto a1 =11;
// int
const
auto a2 =4;
// int
// c style
double res1 =
(double
)(a1)/(
double
)(a2)
;// 其實寫乙個 (double) 就行
cout <<
"res1 = "
<< res1 << endl;
// res1 = 2.75
// c++ style
auto res2 = static_cast<
double
>
(a1)
/ static_cast<
double
>
(a2)
; cout <<
"res2 = "
<< res2 << endl;
// res2 = 2.75
cout <<
typeid
(res2)
.name()
<< endl;
// double
如果在 visual studio 中編寫,且安裝了 resharper c++ 的話,如果按照 c 風格寫的話,會提示你,並幫助你自動修改為 c++ 風格,如下圖所示。
(注:截圖見原文)
上邊的static_cast
不能將const int*
轉成int*,const_cast
就可以,用法為const_cast(expression)
。如下面**
const
int a =10;
const
int* p =
&a;*p =20;
// compile error: cannot assign readonly type 'int const'
int res1 = const_cast<
int>
(a);
// compile error: cannot cast from 'int' to 'int' via const_cast
// only conversions to reference or pointer types are allowed
int* res2 = const_cast<
int*
>
(p);
// ok
也就是說,const_cast<>裡邊的內容必須是引用或者指標,就連把 int 轉成 int 都不行。
對於 const_cast 的使用,其實還有很多不明白的(c++未定義的行為),比如下面三張圖。
(注:截圖見原文)
總結,const_cast 通常是無奈之舉,只是 c++ 提供了一種修改 const 變數的方式,但這種方式並沒有什麼實質性的用處,還是不用的好。const 的變數不要讓它變。
reinterpret_cast 主要有三種強制轉換用途:
改變指標或引用的型別
將指標或引用轉換為乙個足夠長度的整形
將整型轉換為指標或引用型別。
用法為reinterpret_cast (expression)
。
type-id
必須是乙個指標、引用、算術型別、函式針或者成員指標。它可以把乙個指標轉換成乙個整數,也可以把乙個整數轉換成乙個指標(先把乙個指標轉換成乙個整數,在把該整數轉換成原型別的指標,還可以得到原先的指標值)。
我們對映到的型別僅僅是為了故弄玄虛和其他目的,這是所有對映中最危險的。(這句話是c++程式設計思想中的原話)。因此, 你需要謹慎使用 reinterpret_cast。
用法為 dynamic_cast (expression)。
幾個特點如下:
(1)其他三種都是編譯時完成的,dynamic_cast
是執行時處理的,執行時要進行型別檢查。
(2)不能用於內建的基本資料型別的強制轉換
(3)dynamic_cast
要求 <> 內所描述的目標型別必須為指標或引用。dynamic_cast 轉換如果成功的話返回的是指向類的指標或引用,轉換失敗的話則會返回 nullptr
(4)在類的轉換時,在類層次間進行上行轉換(子類指標轉換為父類指標)時,dynamic_cast
和static_cast
的效果是一樣的。在進行下行轉換(父類指標轉化為子類指標)時,dynamic_cast
具有型別檢查的功能,比static_cast
更安全。 向下轉換的成功與否還與將要轉換的型別有關,即要轉換的指標指向的物件的實際型別與轉換以後的物件型別一定要相同,否則轉換失敗。在c++中,編譯期的型別轉換有可能會在執行時出現錯誤,特別是涉及到類物件的指標或引用操作時,更容易產生錯誤。dynamic_cast
操作符則可以在執行期對可能產生問題的型別轉換進行測試。
(5)使用dynamic_cast
進行轉換的,基類中一定要有虛函式,否則編譯不通過(類中存在虛函式,就說明它有想要讓基類指標或引用指向派生類物件的情況,此時轉換才有意義)。這是由於執行時型別檢查需要執行時型別資訊,而這個資訊儲存在類的虛函式表中,只有定義了虛函式的類才有虛函式表(c++中的虛函式基本原理這篇文章寫得不錯,
class base };
class derived : public base };
intmain()
;};class b :public a ;}
;class c };
intmain()
C 四種強制型別轉換
c風格的強制型別轉換 type cast 很簡單,不管什麼型別的轉換統統是 type b type a c 風格的型別轉換提供了4種型別轉換操作符來應對不同場合的應用。const cast,字面上理解就是去const屬性。static cast,命名上理解是靜態型別轉換。如int轉換成char。dy...
C 四種強制型別轉換
1 概述 去const屬性用const cast。基本型別轉換用static cast。多型類之間的型別轉換用daynamic cast。不同型別的指標型別轉換用reinterpreter cast。2 詳解加示例 a const cast 用法 const cast 型別 表示式 用途 刪除con...
C 四種強制型別轉換
c風格的強制型別轉換 type cast 很簡單,不管什麼型別的轉換統統是 type b type a c 風格的型別轉換提供了4種型別轉換操作符來應對不同場合的應用。const cast,字面上理解就是去const屬性。static cast,命名上理解是靜態型別轉換。如int轉換成char。dy...