C 的四種強制型別轉換 通俗解釋

2021-09-24 02:21:53 字數 3019 閱讀 7031

本文討論static_cast<>reinterpret_cast<>

dynamic_cast:動態型別轉換

static_cast: 靜態型別轉換

reinterpret_cast: 重新解釋型別轉換

const_cast: 常量型別轉換

專業的上面很多了,我說說我自己的理解吧:

synamic_cast 一般用在父類和子類指標或應用的互相轉化;

static_cast 一般是普通資料型別(如int m=static_cast(3.14));

reinterpret_cast 很像c的一般型別轉換操作

const_cast 是把cosnt或volatile屬性去掉

介紹大多程式設計師在學c++前都學過c,並且習慣於c風格(型別)轉換。當寫c++(程式)時,有時候我們在使用static_cast<>和reinterpret_cast<>時可能會有點模糊。在本文中,我將說明static_cast<>實際上做了什麼,並且指出一些將會導致錯誤的情況。

泛型(generic types)

/一、 static_cast<> /

float f = 12.3;

float pf = &f;

int n = static_cast(f); // 成功編譯, n = 12

int pn = static_cast(pf); // 錯誤,指向的型別是無關的(譯註:即指標變數pf是float型別,現在要被轉換為int型別)

void* pv = static_cast(pf); //成功編譯

int* pn2 = static_cast(pv); //成功編譯, 但是 *pn2是無意義的記憶體(rubbish)

/*二、 reinterpret_cast<> */

//錯誤,編譯器知道你應該呼叫static_cast<>

//int i = reinterpret_cast(f);

//成功編譯, 但是 pn 實際上是無意義的記憶體,和 pn2一樣

int pi = reinterpret_cast>(pf); //簡而言之,static_cast<> 將嘗試轉換,舉例來說,如float-到-integer,而reinterpret_cast<>簡單改變編譯器的意圖重新考慮那個物件作為另一型別。

指標型別(pointer types)

class cba***

void foo()

};class cbasey

void bar()

};class cderived : public cba***, public cbasey

;情況1:兩個無關的類之間的轉換

// convert between cba**** and cbasey*

// cba**** 和 cbasey之間的轉換

cba*** px = new cba***();

// error, types pointed to are unrelated

// 錯誤, 型別指向是無關的

// cbasey* py1 = static_cast(px);

// compile ok, but py2 is not cba***

// 成功編譯, 但是 py2 不是cba***

cbasey* py2 = reinterpret_cast(px);

// system crash!!

// 系統崩潰!!

// py2->bar();正如我們在泛型例子中所認識到的,如果你嘗試轉換乙個物件到另乙個無關的類static_cast<>將失敗,而reinterpret_cast<>就總是成功「欺騙」編譯器:那個物件就是那個無關類。

cderived* pd = new cderived();

printf(「cderived* pd = %x/n」, (int)pd);

// static_cast<> cderived* -> cbasey* -> cderived*

//成功編譯,隱式static_cast<>轉換

cbasey* py1 = pd;

printf(「cbasey* py1 = %x/n」, (int)py1);

// 成功編譯, 現在 pd1 = pd

cderived* pd1 = static_cast(py1);

printf(「cderived* pd1 = %x/n」, (int)pd1);

// reinterpret_cast

// 成功編譯, 但是 py2 不是 cbasey*

cbasey* py2 = reinterpret_cast(pd);

printf(「cbasey* py2 = %x/n」, (int)py2);

// 無關的 static_cast<>

cbasey* py3 = new cbasey();

printf(「cbasey* py3 = %x/n」, (int)py3);

// 成功編譯,儘管 py3 只是乙個 「新 cbasey()」

cderived* pd3 = static_cast(py3);

printf(「cderived* pd3 = %x/n」, (int)pd3); ---------------------- 輸出 ---------------------------

cderived* pd = 392fb8

cbasey* py1 = 392fbc

cderived* pd1 = 392fb8

cbasey* py2 = 392fb8

cbasey* py3 = 390ff0

cderived* pd3 = 390fec

注意:在將cderived用隱式 static_cast<>轉換到cbasey(第5行)時,結果是(指向)cderived*(的指標向後) 偏移了4(個位元組)(譯註:4為int型別在記憶體中所佔位元組數)。為了知道static_cast<> 實際如何,我們不得不要來看一下cderived的記憶體布局。

cderived的記憶體布局(memory layout)

C 四種強制型別轉換

c風格的強制型別轉換 type cast 很簡單,不管什麼型別的轉換統統是 type b type a c 風格的型別轉換提供了4種型別轉換操作符來應對不同場合的應用。const cast,字面上理解就是去const屬性。static cast,命名上理解是靜態型別轉換。如int轉換成char。dy...

C 四種強制型別轉換

1 概述 去const屬性用const cast。基本型別轉換用static cast。多型類之間的型別轉換用daynamic cast。不同型別的指標型別轉換用reinterpreter cast。2 詳解加示例 a const cast 用法 const cast 型別 表示式 用途 刪除con...

C 四種強制型別轉換

c風格的強制型別轉換 type cast 很簡單,不管什麼型別的轉換統統是 type b type a c 風格的型別轉換提供了4種型別轉換操作符來應對不同場合的應用。const cast,字面上理解就是去const屬性。static cast,命名上理解是靜態型別轉換。如int轉換成char。dy...