1. 程式人生 > >static_cast、dynamic_cast、reinterpret_cast、和const_cast

static_cast、dynamic_cast、reinterpret_cast、和const_cast

轉自:https://blog.csdn.net/gyymen/article/details/53534200

C++的型別轉換符:static_cast、dynamic_cast、reinterpret_cast、和const_cast

形式:class_name <type>(expression) ,其中class_name為以上4種,type是轉換的目標型別,expression是要轉換的值。

1、static_cast 
任何具有明確定義的型別轉換,只要不包含底層const,都可以使用static_const。在編譯期強制轉換。

頂層const:表示指標本身是個常量。如:int *const p; 
底層const:表示指標所指的物件是一個常量。如:int const *p;

該運算子沒有執行時型別檢查來保證轉換的安全性

①用於類層次結構中基類和子類之間指標或引用的轉換。 
進行上行轉換(把子類的指標或引用轉換成基類表示)是安全的; 
進行下行轉換(把基類指標或引用轉換成子類表示)時,由於沒有動態型別檢查,所以是不安全的。

涉及到類,static_cast只能在有相互聯絡的型別中進行相互轉換。

class A
{};
class B:public A
{};
class C
{};

int main()
{
    A* a=new A;
    B* b;
    C* c;
    b=static_cast<B>(a);  // 編譯不會報錯, B類繼承A類
    c=static_cast<B>(a);  // 編譯報錯, C類與A類沒有任何關係
    return 1;
}

②用於基本資料型別之間的轉換,如把int轉換成char,把int轉換成enum。

③把空指標轉換成目標型別的空指標。

④把任何型別的表示式轉換成void型別。

注意:static_cast不能轉換掉expression的const、volitale、或者__unaligned屬性。

2、const_cast 
const_cast只能改變運算物件的底層const,用來移除變數的const或volatile限定符。

const char m = 't';  
const char *cm = &m;  
char *n = const_cast<char*>(cm);  
*n = 'a';  
cout << *n << endl; //輸出a

但是,const_cast是不能用來執行任何型別的轉換的,這樣都會引起編譯錯誤的!

const char m = 't';  
const char *cm = &m;  
int *n = const_cast<int*>(cm);  //編譯出錯,const_cast只能調節型別限定符,不能更改基礎型別
*n = 'a';  
cout << *n << endl;

3、dynamic_cast 
Type必須是類的指標、類的引用或者void *,用於將基類的指標或引用安全地轉換成派生類的指標或引用。

注意: 
(1)dynamic_cast在執行期強制轉換,執行時要進行型別檢查,較安全。 
(2)不能用於內建的基本資料型別的強制轉換。

涉及到類,使用dynamic_cast進行轉換的,基類中一定要有虛擬函式,否則編譯不通過。

對指標進行dynamic_cast,失敗返回null,成功返回正常cast後的物件指標; 
對引用進行dynamic_cast,失敗丟擲一個異常bad_cast,成功返回正常cast後的物件引用。

對於“向上轉換”(即派生類指標或引用轉換為其基類型別)都是安全地。 
對於“向下轉型”有兩種情況: 
第一,基類指標所指物件是派生類型別,這種轉換是安全的; 
第二,基類指標所指物件為基類型別,dynamic_cast在執行時做檢查,轉換失敗,返回結果為0。

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

輸出:

第一種情況轉換成功 
This is Derived class 
第二種情況轉換失敗

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

輸出:

10 
28fedc 
0x28fedc 
char: 
0x28fedc

總結: 
去const屬性用const_cast 
基本型別轉換用static_cast 
多型類之間的型別轉換用daynamic_cast 
不同型別的指標型別轉換用reinterpreter_cast