首頁 > 軟體

詳解C++中常用的四種型別轉換方式

2022-08-18 22:01:41

1.靜態型別轉換:static_cast(exp)

1.1靜態型別轉換主要用於兩種轉換環境

1.1.1 C++內建型別的轉換:與C風格強轉類似。

與c相同的地方:

#include <iostream>
 
using namespace std;
 
int main()
{
    double a=3.14;
 
    cout << static_cast<int>(a) << endl;
 
    return 0;
}

不同的地方就是使用static_cast不能強轉內建型別指標的,這點可以避免C風格中的越界問題。

如圖所示:

1.1.2當有繼承關係存在時的強轉:

如果使用static_cast 由子類向父類別轉型,向上轉型,天然安全安全。(應為子類的空間肯定比父類別的空間大,子類是在繼承父類別的空間上面開闢),程式碼如下:

#include <iostream>
 
using namespace std;
 
class A
{
public:
    int a=100;
 
    void Ashow_info()
    {
        cout<<this->a<<endl;
    }
};
 
class B:public A
{
public:
    int a=200;
    int b=300;
    int c=400;
    void Bshow_info()
    {
        cout<<this->a<<this->b<<this->c<<endl;
    }
};
 
 
int main()
{
   B* a=new B;
   static_cast<A*>(a)->Ashow_info();
 
    return 0;
}

結果圖:

我們可以通過子類安全的存取到父類別中的a值。

如果使用static_cast 由父類別向子類轉型,向下轉型,是不安全。

那麼何時不安全?何時安全?

不安全的情況介紹:

#include <iostream>
 
using namespace std;
 
class A
{
public:
    int a=100;
 
    void Ashow_info()
    {
        cout<<this->a<<endl;
    }
};
 
class B:public A
{
public:
    int a=200;
    int b=300;
    int c=400;
    void Bshow_info()
    {
        cout<<this->a<<this->b<<this->c<<endl;
    }
};
 
 
int main()
{
   A* a=new A;
   static_cast<B*>(a)->Bshow_info();
 
    return 0;
}

結果圖:

如圖所示結果中並沒有出現本應該打出的200,300,400,這就是不知道子類空間是否被開闢而向下存取造成的結果。

安全的情況:

#include <iostream>
 
using namespace std;
 
class A
{
public:
    int a=100;
 
    void Ashow_info()
    {
        cout<<this->a<<endl;
    }
};
 
class B:public A
{
public:
    int a=200;
    int b=300;
    int c=400;
    void Bshow_info()
    {
        cout<<this->a<<this->b<<this->c<<endl;
    }
};
 
 
int main()
{
   A* a=new B;
   static_cast<B*>(a)->Bshow_info();
 
    return 0;
}

結果圖:

如圖所示,此時我們可以打出200,300,400,等數值,說明當我們知道子類空間被開闢時候,就可以安全的向下存取。

2.動態型別轉換:dynamic_cast(exp)

2.1概念

動態型別轉換是依賴於虛擬函式的與繼承關係,沒有虛擬函式,就無法使用動態型別轉換。dynamic_cast是一個安全型別轉換,因為他是依賴於函數實現動態轉型。因為虛表中的第一個Slot位置儲存了型別執行識別資訊。

注意使用的條件為:1)要有繼承關係 2)要有虛擬函式。

這個虛表的結構:

2.2程式碼舉例說明

#include <iostream>
 
using namespace std;
 
class A
{
public:
 
 
    virtual void show_info()
    {
        cout<<"我是父親"<<endl;
    }
};
 
class B:public A
{
public:
 
    void show_info()
    {
        cout<<"我是兒子"<<endl;
    }
};
 
 
int main()
{
   A* a=new B;
   dynamic_cast<B*>(a)->show_info();
 
    return 0;
}

結果圖:

3.常型別轉換:const_case(exp)

就是用來修改const修飾的常參照和常指標的轉換方式

3.1程式碼說明

#include <iostream>
 
using namespace std;
 
int main()
{
    const int& a=100;
 
    const_cast<int&>(a)=200;
 
    cout<<a<<endl;
 
 
    return 0;
}

結果圖:

由圖可知我們修改了常參照的數值。

4. 解釋型別轉換: reinterpret_cast(exp)

4.1概念

這要型別轉換方式,是可以慶用於任何型別,他的底層的實現就是對底層二進位制資料的一個拷貝。所以也是一個不安全的強轉。

4.2由於這個一般都不用,從我們最有可能的會用到的情況下抽出來一種,程式碼如下:

當我們想把一個數的地址,用10進位制的表達出來的時候,如下,光一個int 是裝不下地址的十進位制,所以系統就會給我們報錯。

 這個時候reinterpert_cast就起到了作用,我們可以把他轉為long long型別,如下:

#include <iostream>
 
using namespace std;
 
int main()
{
  int a=10;
 
  int *p=&a;
 
 
  cout<<reinterpret_cast<long long>(p)<<endl;
    return 0;
}

結果圖:

到此這篇關於詳解C++中常用的四種型別轉換方式的文章就介紹到這了,更多相關C++類別型轉換內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com