強制轉(zhuǎn)換符 static_cast, dynamic_cast, reinterpret_cast, const_cast

最近在看 Tensorflow Lite 的源碼,里面用了多種類型轉(zhuǎn)換,我查了下相關(guān)資料,匯總記錄一下。

為啥在 C++ 中會有這么多轉(zhuǎn)換符號

C 風(fēng)格轉(zhuǎn)換風(fēng)格簡單,但是主要存在下面兩點缺點:

  1. 轉(zhuǎn)換隨意,可以在任意類型間轉(zhuǎn)換,轉(zhuǎn)換間差異很大。
  2. 沒有統(tǒng)一的關(guān)鍵字和標(biāo)識符,代碼排查時容易遺漏疏忽。

所以,針對場景需求不同,C++ 提供了四種轉(zhuǎn)換類型來解決上述問題。

  1. 對類型轉(zhuǎn)換做了細(xì)分,提供了四種不同的類型轉(zhuǎn)換,支持不同需求的轉(zhuǎn)換。
  2. 類型轉(zhuǎn)換有了統(tǒng)一的標(biāo)識符,利于代碼排查和檢查。

static_cast

用法:static_cast<type-id>(expression)
把 expression 轉(zhuǎn)換為 type-id 的類型,但沒有類型檢查來保證轉(zhuǎn)換的安全性,主要有以下幾種用法

  • 用于類層次結(jié)構(gòu)中基類和子類之間指針或引用的轉(zhuǎn)換。進行上行轉(zhuǎn)換(把子類的指針或引用轉(zhuǎn)換成基類表示)是安全的;進行下行轉(zhuǎn)換(把基類指針或引用轉(zhuǎn)換成子類表示)時,由于沒有動態(tài)類型檢查,所以是不安全的。
  • 用于基本數(shù)據(jù)類型之間的轉(zhuǎn)換,如把int轉(zhuǎn)換成char,把int轉(zhuǎn)換成enum。這種轉(zhuǎn)換的安全性也要開發(fā)人員來保證。
  • 把空指針轉(zhuǎn)換成目標(biāo)類型的空指針。
  • 把任何類型的表達式轉(zhuǎn)換成void類型。

注意:static_cast不能轉(zhuǎn)換掉expression的const、volitale、或者__unaligned屬性。


dynamic_cast

用法: dynamic_cast<type-id>(expression)

該運算符把 expression 轉(zhuǎn)換成 type-id 類型的對象,type-id 必須是類的指針,類的引用或者 void*,主要用法

  • 類層次間的上行或下行轉(zhuǎn)換,以及類之間的交叉轉(zhuǎn)換

在類層次上行轉(zhuǎn)換時,dynamic_cast 和 static_cast 的效果基本一致,但在下行轉(zhuǎn)換時,dynamic_cast 具有類型檢查功能,如下例子。


class B{
public:
    int m_iNum;
    virtual void foo(); // 運行時檢查類型信息是依賴虛函數(shù),否則會編譯出錯
};

class D:public B{
 public:
    char *m_szName[100];
};

void func(B *pb){
     D *pd1 = static_cast<D *>(pb); // 轉(zhuǎn)換成 D 類型指針,但是訪問 m_szName 是不安全的
     D *pd2 = dynamic_cast<D *>(pb); // 類型檢查,返回 NULL
}

此外,dynamic_cast 還支持交叉轉(zhuǎn)換,如下代碼所示:

class A{
public:
    int m_iNum;
    virtual void f(){}
};
 
class B:public A{
};
 
class D:public A{
};
 
void foo(){
 B *pb = new B;
 pb->m_iNum = 100;
 
 D *pd1 = static_cast<D *>(pb); // 不允許,編譯時出錯
 D *pd2 = dynamic_cast<D *>(pb); // 允許,但值為空指針
 delete pb;
}

reinterpret_cast

用法:reinpreter_cast<type-id> (expression)

type-id 必須是一個指針、引用、算術(shù)類型、函數(shù)指針或者成員指針。它可以把一個指針轉(zhuǎn)換成一個整數(shù),也可以把一個整數(shù)轉(zhuǎn)換成一個指針,簡單來說,它可以將任何指針類型轉(zhuǎn)化成任何其他指針類型。

這個強制轉(zhuǎn)換符還是蠻危險的,一般來說使用場景有兩種:

  • 清楚的知道強制轉(zhuǎn)換時兩者的類型
  • 需要對位進行操作

這個轉(zhuǎn)換符是這四個中最難理解的,我現(xiàn)在也沒完全搞明白,慎重使用。


const_cast

用法:const_cast<type_id> (expression)

該運算符用來修改類型的const或volatile屬性。除了const 或volatile修飾之外, type_id和expression的類型是一樣的。

作用是將常量指針轉(zhuǎn)換成非常量指針,那么對應(yīng)值就可以進行修改了,如下例子所示

const 類的舉例如下:

class B{
 public:
     int m_iNum;
}
 
void foo(){
    const B b1;
    // b1.m_iNum = 100; // 執(zhí)行這句會報錯
    
    B b2 = const_cast<B>(b1);
    b2. m_iNum = 200; // 轉(zhuǎn)換后修改則不會
}

參考鏈接

  1. [C++ Language Tutorial - Type Casting
    ]
  2. reinterpret_cast in C++ | Type Casting operators
  3. 類型轉(zhuǎn)換之reinterpret_cast
  4. 詳解C++的static_cast、dynamic_cast、reinterpret_cast、和const_cast
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容