1. 程式人生 > >C++中四種強制轉換

C++中四種強制轉換

一、簡介

C++中存在四種強制型別轉換,分別是static_cast 、const_cast 、 dynamic_cast 、reinterpret_cast

二、存在原因

我們直到在C語言中有強制型別轉換,可以轉換成合理的型別,那麼我們為什麼要在C++中引入四種強制型別轉化的概念呢?

  • 由於新型別的強制型別轉換可以提供更好的強制控制轉換過程,一旦當程式設計師使用了四種強制型別轉換,其他的人讀程式的時候可以立刻知道這個強制轉換的目的是什麼,方便了我們的閱讀。
  • C語言的強制型別轉換難定位到所有使用強制型別轉換的語句。

三、強制型別轉換的分類

(1)static_cast (靜態轉換)

表示式為 : static_cast (expression)

  • 運算子把expression轉換為type-id型別,當我們需要在內建型別中相互轉換的時候,就可以使用static_cast,即任何標準轉換都可以使用它,但是在執行的過程中沒有檢查和保證轉換的安全性(顯示告訴編譯器,不關心轉換後的精度損失)

它的用法主要有以下三個:

  • 用於基本型別之間的轉換。
int i;
float f = 31.4;
i = static_cast<int>(f);
  • 不能用於基本型別指標之間的轉換。
int i = 1;
char c = 'a';
int* p = &i;
char
* pc =&c; pc = static_cast<char*>(p);//錯誤
  • 用於有繼承關係類物件之間的轉換和類指標之間的轉換
class A
{
};

class B :public A
{
};

class C
{
};

int main()
{
    A* a = new A;
    B* b;
    C* c;
    b = static_cast<B*>(a);
    c = static_cast<C*>(c);//此句會出錯
}

這裡寫圖片描述

注意:

如果涉及到類的話,static_cast只能在有相互聯絡的型別中進行相互轉換,不一定包含虛擬函式。

(2)const_cast

表示式為:const_cast (expression)

  • 此表示式主要用來刪除變數的const屬性
  • 強制型別轉換的目標型別必須是指標或者引用

(3)dynamic_cast

表示式為:dynamic_cast (expression)

  • 主要用來將基類的指標和引用安全的轉化為派生類的指標或者應用。

轉化分兩類:

向上轉換

即派生類指標或引用型別轉換為其基類型別,無論是指標還是引用向上轉換都是安全的。

向下轉換

對於“向下轉型”有兩種情況:

  • 一種是基類指標所指物件是派生類型別的,這種轉換是安全的;
  • 基類指標所指物件為基類型別,在這種情況下dynamic_cast在執行時做檢查,轉換失敗,返回結果為0;
    在引用上,dynamic_cast依舊是常用於“安全的向下轉型”。與指標一樣,引用的向下轉型也可以分為兩種情況,與指標不同的是,並不存在空引用,所以引用的dynamic_cast檢測失敗時會丟擲一個bad_cast異常。

特點:

  • 用於有繼承關係的指標間的轉換
  • 用於有交叉關係的類指標間的轉換
  • 具有型別檢查的功能(轉換不成功返回NULL)
  • 含有虛擬函式的類(定義的類中必須要有虛擬函式)
#include<iostream>  
using namespace std;

class Base
{
public:
    Base() {};
    virtual void Show()
    { 
        cout << "This is Base calss";
    }
};

class Derived :public Base
{
public:
    Derived() {};
    void Show() 
    {
        cout << "This is Derived class";
    }
};

int main()
{
    //這是第一種情況  
    Base* base = new Derived;
    if (Derived *der = dynamic_cast<Derived*>(base))
    {
        cout << "第一種情況轉換成功" << endl;
        der->Show();
        cout << endl;
    }
    //這是第二種情況  
    Base * base1 = new Base;
    if (Derived *der1 = dynamic_cast<Derived*>(base1))
    {
        cout << "第二種情況轉換成功" << endl;
        der1->Show();
    }
    else
    {
        cout << "第二種情況轉換失敗" << endl;
    }
    delete(base);
    delete(base1);

    return 0;
}

注意:

dynamic_cast在轉換之前會進行檢查,如果轉換失敗指標返回,應用丟擲bad_cast異常。

(4)reinterpret_cast

  • 用於指標型別間的強制轉換
  • 用於整數和指標型別間的強制轉換
#include<iostream>  

using namespace std;

int main()
{
    int a = 10;
    int *i = &a;
    long pc = reinterpret_cast<long>(i);//把一個指標轉換為一個整數,即取出地址值  
    char *str = reinterpret_cast<char *>(i);//把int*轉換為char *(比int型小),無輸出  
    long *l = reinterpret_cast<long *>(i);//把int *轉換為long *(比int型大),取出地址值(即i值)輸出  

    cout << *i << endl;
    cout << hex << pc << endl;
    cout << i << endl;
    cout << "char:" << str << endl;
    cout << l << endl;

    return 0;
}

注意

reinterpret_cast不能用於非指標型別的轉換。

四、總結

基本型別轉換用static_cast。

去const屬性用const_cast。

多型類之間的型別轉換用daynamic_cast。

不同型別的指標型別轉換用reinterpreter_cast。