1. 程式人生 > >類型轉換:static_cast、reinterpret_cast等

類型轉換:static_cast、reinterpret_cast等

通用 key nbsp 四種 double 語言 繼承關系 丟了 安全性

一、隱式類型轉換

系統自動進行,不需要程序開發人員介入。

int m = 3 + 45.6;// 48 把小數部分截掉,也屬於隱式類型轉換的一部分

double b = 3 + 45.6; // 48.6

二、顯示類型轉換(強制類型轉換)

int key = 5 % 3.2; // 語法錯誤
int k   = 5 % (int)3.2; // 強制轉換為3,C語言風格的類型轉換
int k1  = 5 % int(3.2); // 函數風格的強制類型轉換

C++類型強制類型轉換分為4種:

這四種強制類型轉換被稱為命名的強制類型轉換;目的是為了提供更加豐富的含義和功能,更好的類型檢查機制。

通用形式:強制類型轉換名<type>(express)

(1)static_cast:靜態轉換,編譯的時候就會進行類型轉換的檢查

代碼中要保證類型轉換的安全性與正確性,含義與C語言的強制類型轉換意義差不多。C風格的強制類型轉換以及編譯器能夠進行的隱式類型轉換,都可以用static_cast類型顯示完成。

可用於:

(a)相關類型轉換,比如整型和實型之間的轉換

double f = 100.43f;
int i = (int)f; // C風格的
int i2 = static_cast<int>(f); // C++風格的強制類型轉換 顯示

(b)子類轉換為父類的時候(繼承關系),也可以用static_cast

calss A{};
class B : public A{}; // 公有繼承
B b;
A a = static_cast<A>(b);// 將子類轉換為父類

(c)void *與其他的類型指針之間的轉換,void *無類型指針,可以指向任何類型的指針(萬能指針)

int i = 10;
int *p = &i;
void *q = static_cast<void *>(p); // int *轉換為void *
int *dq = static_cast<int *>(q);  // 將void *轉換回int *

一般不能用於:

(a)一般不能用於指針類型之間的轉換比如int * 轉double *,float *轉 double*等等

double f = 100.0f;
double *pf = &f;
// int *if = static_cast<int *>(pf); // 不可以
// float *if = static_cast< float *>(pf); // 不可以

(2)dynamic_cast

主要應用於運行時類型識別與檢查。主要用來父類型和子類型之間轉換用(父類型指針指向子類型對象,然後用dynamic_cast把父指針類型轉換為子指針類型)

(3)const_cast

去除指針或引用的const屬性,該指針能將const性質轉換掉,編譯時類型轉換。

cons tint ai = 90;
//int ai2 = const_cast<int>(ai); // ai不是指針或引用,不能轉換
const int *pai = &ai;
const int *pai2 = const_cast<int *>(pai); // 語法正確
*pai2 = 120; // 這種寫值行為,屬於一種未定義行為,盡量不要這麽寫
cout <<ai << endl; // 90
cout << *pai << endl; // 120
cons tint ai = 90;
int *pai2 = (int *)&ai; // 語法正確
*pai2 = 120; // 這種寫值行為,屬於一種未定義行為,盡量不要這麽寫
cout << ai << endl; // 90
cout << *pai2 << endl; // 120

(4)reinterpret_cast

編譯的時候就會進行類型轉換的檢查,翻譯,重新解釋

將操作數內容解釋為另一種不同的類型。

處理無關系的轉換,也就是兩個類型轉換之間沒有什麽關系;就等於什麽都可以轉換。

(a)將一個整型(地址)轉換為指針,一種類型指針轉換為另一種類指針,按照轉換後的內容重新解釋內存中的內容。

(b)也可以從一個指針轉換為整型

int i = 10;
int *p = &i;
int *p2 = reinterpret_cast<int *>(&i);
char *pc = reineterpret_cast<char *>(pi);
int I = 10;
int *p = &I;
void *pvoid = reinterpret_cast<void *>(p);
int *p1 = reinterpret_cast<int *>(pvoid);
// 被認為是危險的類型轉換

int iv1 = 100;
long long lv1 = 8898899400;// 88億  十六字節:2 126A 6DC8
int *piv1 = (int *)iv1; // C語言風格 //0X00000064
int *piv2 = reinterpret_cast<int *>(iv1);//0X00000064
piv2 = reinterpret_cast<int *>(lv1); // OX126A 6DC8 把前面的2丟了,因為piv2是4字節的
long long ne = reinterpret_cast<long long>(piv2); // 指針類型轉long long
// 308964808 十六進制:126A 6DC8

三、總結

(1)強制類型轉換,不建議使用;強制類型轉換能夠抑制編譯器報錯。

(2)了解類型轉換符,方便閱讀別人代碼。

類型轉換:static_cast、reinterpret_cast等