類型轉換:static_cast、reinterpret_cast等
一、隱式類型轉換
系統自動進行,不需要程序開發人員介入。
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等