C++中的型別轉換關鍵字
阿新 • • 發佈:2019-01-27
本文參考自狄泰軟體學院:《C++深度剖析》
C方式的強制型別轉換
示例程式碼:
typedef void(PF)(int); //定義一個函式型別PF
struct Point
{
int x;
int y;
};
int main()
{
int v = 0x12345;
PF* pf = (PF*)v; //將v強制型別轉換為函式指標pf
char c = char(v);
Point* p = (Point*)v; //將v強制型別轉換為結構體指標
pf(5);
printf("p->x = %d\n" , p->x);
printf("p->y = %d\n", p->y);
return 0;
}
編譯時無警告無錯誤。執行時發生段錯誤(記憶體錯誤),明顯的,C語言中的強制型別轉換存在問題。
1. 過於粗暴:任意型別之間都可以進行轉換,編譯器很難判斷其正確性
2. 難於定位:在原始碼中無法快速定位所用使用強制型別轉換的語句(沒有特殊關鍵字,關鍵字就是資料型別)
問題:強制型別轉換在實際工程專案中用得很多,但是卻很難完全避免!如何進行更加安全可靠的轉換?
C++中的型別轉換
為了解決C語言強制型別的問題,C++將強制型別轉換分為4種不同的型別。
1. 這4種新式型別轉換以C++關鍵字的方式出現
2. 編譯器能夠幫助檢查潛在的問題
3. 非常方便在程式碼中定位
4. 支援動態型別識別(dynamic_cast)
static_cast強制型別轉換
- 用於基本型別間的轉換(int,float,double..)
- 不能用於基本型別指標間的轉換(int*,float*)
- 用於有繼承關係類物件之間的轉換和類指標之間的轉換
const_cast強制型別轉換
- 用於去除變數的只讀屬性
- 強制轉換的目標型別必須是指標或引用
reinterpret_cast強制型別轉換
- 用於指標型別間的強制轉換
- 用於整數和指標型別間的強制轉換
dynamic_cast強制型別轉換
- 用於有繼承關係的類指標間的轉換
- 用於有交叉關係的類指標間的轉換
- 具有型別檢查的功能
- 需要虛擬函式的支援
這四種類型轉換並不是相互獨立的。同一個型別轉換並不只是四選一,而是可能選擇多個。
示例程式碼:新型型別轉換的使用
void static_cast_demo()
{
int i = 0x12345;
char c = 'c';
int* pi = &i;
char* pc = &c;
c = static_cast<char>(i); //新式強制型別轉換的用法
pc = static_cast<char*>(pi); //Error,不支援基本型別指標間的轉換
}
void const_cast_demo()
{
const int& j = 1;
int& k = const_cast<int&>(j);
const int x = 2;
int& y = const_cast<int&>(x);
int z = const_cast<int>(x); //Error
k = 5;
printf("k = %d\n", k); //k = 5
printf("j = %d\n", j); //j = 5
y = 8;
printf("x = %d\n", x); //x = 2
printf("y = %d\n", y); //y = 8
printf("&x = %p\n", &x); //&x和&y的地址相同
printf("&y = %p\n", &y);
}
void reinterpret_cast_demo()
{
int i = 0;
char c = 'c';
int* pi = &i;
char* pc = &c;
pc = reinterpret_cast<char*>(pi);
pi = reinterpret_cast<int*>(pc);
pi = reinterpret_cast<int*>(i);
c = reinterpret_cast<char>(i);
}
void dynamic_cast_demo()
{
int i = 0;
int* pi = &i;
char* pc = dynamic_cast<char*>(pi);
}
int main()
{
static_cast_demo();
const_cast_demo();
reinterpret_cast_demo();
dynamic_cast_demo();
return 0;
}