一、dynamic_cast
使用dynamic_cast
一個繼承層次內進行轉化的指針/引用。dynamic_cast依賴於RTTI信息,在轉換時,dynamic_cast會檢查轉換的source對象是否真的可以轉換成target類型,這種檢查不是語法上的,而是真實情況的檢查。被轉換的類型必須是多態(即有虛函數)。使用這個會影響運行效率,一般情況下也是不使用的。能在編譯時解決掉的問題沒必要留到運行時、能用多態搞定的事情也沒必要使用 dynamic_cast 和 typeid 等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
if (pb2) {
}
|
在上面的代碼段中,如果 pb 指向一個 D 類型的對象,pd1 和 pd2 是一樣的,並且對這兩個指針執行 D 類型的任何操作都是安全的;但是,如果 pb 指向的是一個 B 類型的對象,那麼 pd1 將是一個指向該對象的指針,對它進行 D 類型的操作將是不安全的(如訪問 m_szName),而 pd2 將是一個空指針。
另外要注意:B 要有虛函數,否則會編譯出錯;static_cast則沒有這個限制。
二、static_cast
使用static_cast
普通類型轉換。
①用於類層次結構中基類(父類)和派生類(子類)之間指針或引用的轉換。
進行上行轉換(把派生類的指針或引用轉換成基類表示)是安全的;
進行下行轉換(把基類指針或引用轉換成派生類表示)時,由於沒有動態類型檢查,所以是不安全的。
②用於基本數據類型之間的轉換,如把int轉換成char,把int轉換成enum。這種轉換的安全性也要開發人員來保證。這種不加static_cast進行轉換,一般編譯器會提示告警,加static_cast可以消除告警提示。
③把空指針轉換成目標類型的空指針。
④把任何類型的表達式轉換成void類型。
三、reinterpret_cast
使用reinterpret_cast
的位模式的低級別重讀。使用時要格外小心。reinterpret_cast與編譯器平臺相關,因此不具有移植性,使用範圍也有限。
四、const_cast
使用const_cast
鑄造遠const/volatile
。除非你使用const不正確的API,否則請避免這種情況。一般就是別人的庫API裏,但我們要傳入的參數是const類型,而庫的API要的參數沒要求const,這裏編譯器就會報錯,並且我們知道庫API那個函數不會修改我們代入的參數,這裏就可以用const_cast來處理,避免編譯器編譯不過。
五、typeid 打印對象名稱
BaseA* pa;
BaseA baseA;
pa = &baseA;
cout << “baseA” << " " << typeid(baseA).name() << endl;
cout << “pa” << " " << typeid(pa).name() << endl;
六、typeof
typeof()關鍵字常見用法一共有以下幾種。
-
不用知道函數返回什麼類型,可以使用typeof()定義一個用於接收該函數返回值的變量
typeof(fun()) r1;//定義一個變量r1,用於接收函數fun()返回的值,假如我們不知道fun()返回類型也可以這樣用
2.在宏定義中動態獲取相關結構體成員的類型
#define swap(x,y) \
{ typeof(x) temp; \ -->根據類型定義一個臨時變量temp
temp = x;\
x = y;\
y = temp;\
}
3. 做類型轉換時的對象類型聲明
const PROTOCOL_FORMAT::SPacketHead * pHead = (typeof(pHead)) rPackRecv.getHeadData();
參考:https://www.zhihu.com/question/22445339