天天看點

C++:18---強制類型轉換(static_cast、const_cast、dynamic_cast、reinterpret_cast)一、static_cast二、const_cast三、reinterpret_cast四、dynamic_cast

舊式的強制類型轉換

  • 在早期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會去除編譯器的警告,但是我們必須自己清楚轉換有效,否則轉換無效可能會産生未定義的結果

示範案例

  • 我們将一個整型對象轉換為double類型
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 = &num; //任何非常量對象的位址都能存入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對象轉換為非const對象
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

繼續閱讀