1. 程式人生 > 其它 >C++型別轉換:static_cast、reinterpreter_cast、dynamic_cast、const_cast

C++型別轉換:static_cast、reinterpreter_cast、dynamic_cast、const_cast

C++支援C語言的強制型別轉換,並提供了四種應對各種的強制型別函式,以下對C++的強制型別轉換做簡單介紹。

1.C語言風格強制型別轉換

1 TypenameB b;
2 TypenameA a=(TypenameA)b;

C語言風格型別強制轉換存在較多安全隱患,例如:

1)把一個指向 const 物件的指標轉換成指向非 const 物件的指標;

2)把一個指向基類物件的指標轉換成指向一個派生類物件的指標;

3)C 風格的轉換不容易查詢,他由一個括號加上一個識別符號組成, 而這樣的東西在 c++程式裡一大堆。
因此,C++提供了四種轉換型別。

2.C++ 四種強制型別轉換

static_cast 靜態型別轉換

該運算子把expression轉換為type-id型別,但沒有運行時型別檢查來保證轉換的安全性。它主要有如下幾種用法:

1)用於基類(父類)和派生類(子類)之間指標或引用的轉換。

進行上行轉換(把派生類的指標或引用轉換成基類表示)是安全的;

進行下行轉換(把基類指標或引用轉換成派生類表示)時,由於沒有動態型別檢查,所以是不安全的。

2)用於基本資料型別之間的轉換,如把int轉換成char,把int轉換成enum。基本轉換的安全性由開發者保證。

3)把空指標轉換成目標型別的空指標、把任何型別的表示式轉換成void型別。

注意:static_cast不能轉換掉expression的const、volatile、或者__unaligned屬性。

1 double a=1.12;
2 int b= static_cast<int> (a); //c++的新式的型別轉換運算子  
3 char *p1 = "hello" ;//指標與void指標轉換
4 int *p2 = nullptr;
5 p2 = (int *)p1;
6 //p2 = static_cast<int *> (p1); ///不能轉換指標型別“static_cast”: 無法從“char *”轉換為“int *”

reinterpreter_cast 重解釋型別轉換

可以用於任意型別指標之間的轉換,沒有安全性檢測。

1 int *a = new int
; 2 double *b = reinterpret_cast<double *>(a);

const_cast去掉const屬性轉換

1)常量指標被轉化成非常量的指標,並且仍然指向原來的物件;
2)常量引用被轉換成非常量的引用,並且仍然指向原來的物件;
3)const_cast一般用於修改指標。如const char *p形式;

1 const double a = 7;
2 const double* p = &a;
3 double* q = const_cast<double*>(p);
4 *q = 20; //通過q寫值是未定義的行為
5 cout << *q<<"   "<<a<<"   "<<*p << endl;

執行輸出

20   7   20

強制轉換後,*q 與*p不再指向a,*q 與*p依然指向同一地址空間,且能夠通過*q修改地址對應變數的值,但*p不能。

1 double a = 7;
2 const double& p = a;
3 double& q = const_cast<double&>(p);
4 q = 20; //通過q寫值是未定義的行為
5 cout << q<<"   "<<a<<"   "<<p << endl;

執行輸出

20   20   20

強制轉換後,q 與p依然指向a,且能夠通過q修改地址對應變數的值,但p不能。

dynamic_cast動態型別轉換

1)其他三種都是編譯時完成的,dynamic_cast是執行時處理的,執行時要進行型別檢查。

2)不能用於內建的基本資料型別的強制轉換。

3)dynamic_cast轉換如果成功的話返回的是指向類的指標或引用,轉換失敗的話則會返回NULL。

4)使用dynamic_cast進行轉換的,基類中一定要有虛擬函式,否則編譯不通過。

dynamic_cast用於類繼承層次間的指標或引用轉換。主要還是用於執行“安全的向下轉型(safe downcasting)”,也即是基類物件的指標或引用轉換為同一繼承層次的其他指標或引用。至於“先上轉型”(即派生類指標或引用型別轉換為其基類型別),本身就是安全的,儘管可以使用dynamic_cast進行轉換,但這是沒必要的, 普通的轉換已經可以達到目的,畢竟使dynamic_cast是需要開銷的