舊式的強制類型轉換
- 在早期C/C++中,顯式地進行強制類型的轉換有以下兩種形式:
C++:18---強制類型轉換(static_cast、const_cast、dynamic_cast、reinterpret_cast)一、static_cast二、const_cast三、reinterpret_cast四、dynamic_cast
C++的新式強制類型轉換
C++:18---強制類型轉換(static_cast、const_cast、dynamic_cast、reinterpret_cast)一、static_cast二、const_cast三、reinterpret_cast四、dynamic_cast - cast-name可以是:static_cast、const_cast、dynamic_cast、reinterpret_cast
- type是:轉換的目标類型
避免強制類型轉換
- 強制類型轉換幹擾了正常的類型檢查,是以強烈建議程式員避免使用強制類型轉換
- 這個建議對于reinterpret_cast尤其使用,因為此類類型轉換總是充滿了風險
一、static_cast
- 功能:用來強迫隐式類型轉換,或稱為顯式的類型轉換
- static_cast還可以将一個左值轉換為右值引用,介紹可以參閱:https://blog.csdn.net/qq_41453285/article/details/104447573
- 例如:
- 将非const對象轉換為const對象(但是不能将底層const對象轉換為非const對象,這個隻有const_cast才能做到)
- 将int轉換為double,反之亦然
- 也可以将void*指針轉換為其他類型指針,将pointer-to-base轉換為pointer-to-derived
- 注意事項:
- 使用static_cast會去除編譯器的警告,但是我們必須自己清楚轉換有效,否則轉換無效可能會産生未定義的結果
示範案例
int i = 10, j = 1;
double slope1 = i / j; //一般的強制類型轉換,編譯器可能會報出警告
double slope2 = static_cast<double>(j) / j; //顯式地強制類型轉換,編譯器無警告
- 當我們把較大的算術類型指派給較小的類型時,一般的強制類型轉換編譯器會發出警告
- 但是當我們使用static_cast後,編譯器就不會報出警告
示範案例
- static_cast對于編譯器無法自動執行的類型轉換也非常有用
- 例如我們可以使用static_cast找回存在于void*指針中的值:
double num = 3.14;
void *p = # //任何非常量對象的位址都能存入void*
double *dp = static_cast<double*>(p); //将void*轉換回初始的指針類型
二、const_cast
- 功能:用來将對象的常量性移除
- 注意事項:
- 隻能改變運算對象的底層const
- const_cast隻能改變表達式的常量屬性,而不能改變表達式的資料類型
- const_cast常用于有函數重載的上下文,參閱:https://blog.csdn.net/qq_41453285/article/details/84843039
示範案例
const char *pc;
//正确,但是通過p寫值是未定義的行為
char *p = const_cast<char*>(pc);
- 當我們去掉某個對象的const性質之後,編譯器就不再阻止我們對該對象進行寫操作了,是以寫操作會産生未定義的後果
示範案例
- const_cast隻能改變表達式的常量屬性,而不能改變表達式的資料類型
const char* cp;
//錯誤,static_cast不能去除const性質
char*q = static_cast<char*>(cp);
//正确,字元串常量值可以轉換為string類型
static_cast<string>(cp);
//錯誤,const隻能去除const性質,但是不能進行資料類型的轉換
const_cast<string>(cp);
三、reinterpret_cast
- 功能:通常為運算對象的位模式提供較低層次上的重新解釋
- 例如将一個pointer-to-int轉換诶一個int
- 使用reinterpret_cast是非常危險的,我們必須自己編寫正确的代碼
- reinterpret_cast本質上依賴于機器。要向安全地使用reinterpret_cast必須對設計的類型和編譯器實作轉換的過程都非常了解
示範案例
int *ip;
char *pc = reinterpret_cast<char*>(ip);
- 我們必須牢記pc所指的真是對象是一個int而不是字元
- 如果把pc當成普通的字元指針使用那麼就會産生未定義的後果。例如:
int *ip;
char *pc = reinterpret_cast<char*>(ip);
//編譯器雖然不報錯,但是後果未定義
string str(pc);
四、dynamic_cast
- dunamic_cast支援運作時類型識别,在另外一篇文章介紹:https://blog.csdn.net/qq_41453285/article/details/104704568