4-11.3 C++中的顯式類轉換
阿新 • • 發佈:2022-01-18
目錄
。
static_cast
1.用來改變基本型別:一般是高精度轉低精度
顯示地告訴程式閱讀者和編譯器,不考慮高精度想低精度轉換時造成的精度損失
#include<iostream> using namespace std; int main(){ double d = 2.1; int i = 6; int res = i/d; //i被隱式地轉換為double res=6/2.1 = 2 cout<<res<<endl; //輸出2 res = i/static_cast<int>(d); //d被強制轉換為int res = 6/2 = 3 cout<<res<<endl; //輸出3 return 0; }
2.恢復void* 指標型別
#include<iostream>
using namespace std;
int main(){
int i = 2;
void *p = &i; //無法通過p得到它所指物件的值
int *q = static_cast<int*>(p); //將其轉換為int*,得到其所指向的值
cout<<*q<<endl; //輸出2
return 0;
}
注意:void*在強制型別轉換時只能轉換為原來的對應型別,如例子中,只能轉換為int*,否則會產生未定義行為
const_cast
用來去除底層const(low-level const)
#include<iostream>
using namespace std;
int main(){
const char *pc;
char *p = const_cast<char*>(pc); //把pc的底層const去除,否則無法對p進行初始化(p不是const)
int *ip = static_cast<int*>( const_cast<char*>(pc)); //去除const後再改變基本型別
return 0;
}
注:1.const_cast可以去除底層const,但不代表轉換後的指標可以改變其指向的值,如果*p是一個const物件,依然不能用p改變其值
2.const_cast只能去除const,不能改變物件的原型別,const_cast<string>(pc);
是不行的,改用static_const<string>(pc);
。
const_cast在函式過載時運用廣泛
reinterpret_cast
為運算物件的位模式提供較低層次的重新解釋,但並不真正改變物件型別
#include<iostream>
using namespace std;
int main(){
int *ip;
char *pc = reinterpret_cast<char*>(ip); //pc所指的真實物件實際上是int型別而不是字元
string s(pc); //用int*來初始化string顯然會出現問題,但由於有顯示型別轉換,所以編譯器不會報錯
cout<<s<<endl;
return 0;
}
使用reinterpret_cast是非常危險的,用pc初始化str的例子很好地證明了這一點。其中的關鍵問題是型別改變了,但編譯器沒有給出任何警告或者錯誤的提示資訊。當我們用一個int的地址初始化pc時,由於顯式地聲稱這種轉換合法,所以編譯器不會發出任何警告或錯誤資訊。接下來再使用pc時就會認定它的值是char*型別,編譯器沒法知道它實際存放的是指向int的指標。最終的結果就是,在上面的例子中雖然用pc初始化 str 沒什麼實際意義,甚至還可能引發更糟糕的後果,但僅從語法上而言這種操作無可指摘。查詢這類問題的原因非常困難,如果將ip 強制轉換成pc的語句和用pc初始化 string物件的語句分屬不同檔案就更是如此。
所以在程式設計時經歷避免強制型別轉換
舊式型別轉換
(type)expr
:c語言風格的函式型別轉換,其含義並不清晰,根據語境會分別具有static\_cast
、const\_cast
、reinterpret\_cast
的功能。
int *ip;
char *pc = (char*)ip; //作用同reinterpret_cast
所以追蹤錯誤時會更加困難,不建議使用。