C++四種類型轉換總結


C風格的強制類型轉換很簡單,均用 Type b = (Type)a 形式轉換。C++風格的類型轉換提供了4種類型轉換操作符來應對不同場合的應用,如下表:

轉換類型操作符 作用
const_cast 去掉類型的const或volatile屬性
static_cast 無條件轉換,靜態類型轉換
dynamic_cast 有條件轉換,動態類型轉換,運行時檢查類型安全(轉換失敗返回NULL)
reinterpret_cast 僅重新解釋類型,但沒有進行二進制的轉換

1、const_cast

去掉類型的const或volatile屬性

int main() {

    struct T {
        int i;
    };

    const T a;
    //a.i = 10;  //直接修改const類型,編譯錯誤
    T &b = const_cast<T&>(a);
    b.i = 10;

    return 0;
}

2、static_cast

類似C風格的強制轉換,進行無條件轉換,靜態類型轉換:

1)基類和子類之間的轉換:其中子類指針轉換為父類指針是安全的,但父類指針轉換為子類指針是不安全的(基類和子類之間的動態類型轉換建議用dynamic_cast)。

2)基本數據類型轉換,enum,struct,int,char,float等。static_cast不能進行無關類型(如非基類和子類)指針之間的轉換。

3)把任何類型的表達式轉換成void類型。

4)static_cast不能去掉類型的const、volatile屬性(用const_cast)。

int main() {

    int n = 6;
    double d = static_cast<double>(n);     //基本類型轉換
    int *pn = &n;
    double *d = static_cast<double*>(&n);  //無關類型轉換,編譯錯誤
    void *p = static_cast<void*>(pn);

    return 0;
}

3、dynamic_cast

有條件轉換,動態類型轉換,運行時檢查類型安全(轉換失敗返回NULL):

1)安全的基類和子類之間的轉換。

2)必須有虛函數。

3)相同基類不同子類之間的交叉轉換,但結果返回NULL。

class Base {
public:
    int _i;
    virtual void foo() {}; //基類必須有虛函數。保持多態特性才能使用dynamic_cast
};

class Sub : public Base {
public:
    char *_name[100];
    void Bar() {};
};

int main() {

    Base* pb = new Sub();
    Sub* ps1 = static_cast<Sub*>(pb);  //子類->父類,靜態類型轉換,正確但不推薦
    Sub* ps2 = dynamic_cast<Sub*>(pb); //子類->父類,動態類型轉換,正確

    Base* pb2 = new Base();
    Sub* ps21 = static_cast<Sub*>(pb2); //父類->子類,靜態類型轉換,危險!訪問子類_name成員越界
    Sub* ps22 = dynamic_cast<Sub*>(pb2);//父類->子類,動態類型轉換,安全,但結果為NULL

    return 0;
}

4、reinterpret_cast

僅重新解釋類型,但沒有進行二進制的轉換:

1)轉換的類型必須是一個指針,應用、算術類型、函數指針或者成員指針。

2)在比特級別上進行轉換,可以把一個指針轉換成一個整數,也可以把一個整數轉換成一個指針(先把一個指針轉換成一個整數,在把該整數轉換成原類型的指針,還可以得到原先的指針值)。但不能將非32bit的實例轉成指針。
3) 最普通的用途就是在函數指針類型之間進行轉換。
4) 很難保證移植性。

int doSomething() { 
    return 0; 
};

int main() {
    typedef void(*FuncPtr)(); //FuncPtr is 一個指向函數的指針,該函數沒有參數,返回值類型為 void
    FuncPtr funcPtrArray[10]; //10個FuncPtrs指針的數組 讓我們假設你希望(因為某些莫名其妙的原因)把一個指向下面函數的指針存入funcPtrArray數組:

    funcPtrArray[0] = &doSomething;// 編譯錯誤!類型不匹配,reinterpret_cast可以讓編譯器以你的方法去看待它們:funcPtrArray
    funcPtrArray[0] = reinterpret_cast<FuncPtr>(&doSomething); //不同函數指針類型之間進行轉換

    return 0;
}

總結

去const屬性用const_cast

基本類型轉換用static_cast

多態類之間的類型轉換用dynamic_cast

不同類型的指針類型轉換用reinterpret_cast

 


免責聲明!

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



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