1. 程式人生 > >C++中的型別轉換關鍵字

C++中的型別轉換關鍵字

本文參考自狄泰軟體學院:《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強制型別轉換

  1. 用於基本型別間的轉換(int,float,double..)
  2. 不能用於基本型別指標間的轉換(int*,float*)
  3. 用於有繼承關係類物件之間的轉換和類指標之間的轉換

const_cast強制型別轉換

  1. 用於去除變數的只讀屬性
  2. 強制轉換的目標型別必須是指標或引用

reinterpret_cast強制型別轉換

  1. 用於指標型別間的強制轉換
  2. 用於整數和指標型別間的強制轉換

dynamic_cast強制型別轉換


  1. 用於有繼承關係的類指標間的轉換
  2. 用於有交叉關係的類指標間的轉換
  3. 具有型別檢查的功能
  4. 需要虛擬函式的支援

這四種類型轉換並不是相互獨立的。同一個型別轉換並不只是四選一,而是可能選擇多個。
示例程式碼:新型型別轉換的使用

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;
}