強制類型轉換詳解 C++———— static_cast、dynamic_cast、const_cast、reinterpret_cast

1 起因

之前使用類型轉換,一般都會使用

short a = 10;
int b = (int) a;

然後Qt creator就會爆出:
在這裏插入圖片描述
原因就是使用了舊時的風格,也就是C語言的風格,存在安全隱患。

因此我查詢了C++如何進行強制類型轉換。

2 C++強制類型轉換

靜態static_cast<要轉換的類型>被轉換的變量,動態dynamic_cast<要轉換的類型>被轉換的變量

區別:
static_cast<>是在編譯時檢測類型,dynamic_cast<>是在運行時檢測類型。

當存在要轉換的類型爲:從基類指向派生類時,由於派生類中可能存在基類沒有的成員函數或變量,於是雖然static_cast<>編譯時,不會報錯,但是運行時,如果訪問量了基類中沒有但派生類中有的變量或函數,就可能會出現越界錯誤(段錯誤),程序被異常終止。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
測試程序:

#include<iostream>
#include <string>

using namespace std;

class A
{
 public:
  int a;
 virtual ~A(){}
  //基類中必須有虛函數是因爲:
  //dynamic_cast<>要求所涉及的類至少具有1個虛擬方法,
  //該方法允許編譯器(如果支持RTTI)執行此附加檢查。

};

class B : public A
{
 public :
  string m;
  double n;
  short l;
  void f(){
     m = "hello";
  }
};


int main(){
       A *Pa = new A();
    B *Pb = NULL;

    Pb = static_cast<B*>(Pa); //下行轉換,基類指針轉換成子類
    //Pb = dynamic_cast<B*>(Pa); 

    // Pb->m = "hehehe";
    Pb->l = 7;
    Pb->f();
    
    cout<<Pb->l<<endl;//能輸出的原因的爲:基類中剛好有int類型的變量,int和int剛好可以類型轉換(換成short或者double也可以)
    cout<<Pb->m <<endl;


    return 0;
}

運行結果如下:上面的爲static_cast<>,下面的爲dynamic_cast<>。在這裏插入圖片描述
也就是雖然訪問m越界了,但是還是能輸出結果(把類A下面的內存(未初始化的)轉換爲int,這樣非常不安全,後面可能會出現莫名其妙的錯誤)。

但是dynamic_cast<>,卻輸出了段錯誤,保證了程序的安全性。

3 總結

使用dynamic_cast<>的情況:

  • 類層次結構中父類和子類之間指針和引用的轉換(運行時,類型檢查,保證了程序的安全性)【可以用於基類指針指向派生類的指針】
    其他情況使用static_cast<>。

使用static_cast<>的情況:

  • 基本數據類型間的類型轉換
  • 把空指針轉換成目標類型的空指針
  • 把任何類型的表達式類型轉換成void類型
  • 用於類層次結構中父類和子類之間指針和引用的轉換。(僅用於指向派生類的指針,訪問指向父類的內容

4 衍生

const_cast<>
作用:把常量對象改爲非常量對象。
注意:

  • 被轉換的變量類型必須爲引用或指針。
  • 在指針或引用更改值後,原始常量中值依然不變,只有變量或者指針的值改變。
    使用場景:
    當函數爲常量函數時,想要改變常量函數的中的參數,可以使用。

reinterpret_cast<>
作用:

  • 改變指針或引用的類型(地址)
  • 將指針或引用轉換爲一個足夠長度的整形(取決於操作系統的參數)
  • 將整型轉換爲指針或引用類型
    注意:
  • 強制轉換過程僅僅只是比特位的拷貝
  • 不能去除const修飾符
    使用場景:
  • 主要用於將轉換後的類型值轉換回到其原始類型(做hash函數輔助)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章