C++繁瑣的類型轉換,C++小知識之四種類型轉換

c語言基礎 發佈 2020-03-31T03:59:13+00:00

有時,編程的過程中需要將值從一種數據類型轉換為另一種數據類型。在C語言中,強制類型轉換的方式為(Type)Expression,另外還有一種現在已經不用的舊式寫法Type(Expression),這兩種方式是等價的。


有時,編程的過程中需要將值從一種數據類型轉換為另一種數據類型。

在C語言中,強制類型轉換的方式為(Type)Expression,另外還有一種現在已經不用的舊式寫法Type(Expression),這兩種方式是等價的。

但是,C語言的強制類型轉換方式存在一些問題:過於粗暴,可以在任意類型之間進行轉換,編譯器很難判斷其正確性,難於定位,在原始碼中無法快速定位所有使用強制類型轉換的語句。

然而,強制類型轉換在實際工程中幾乎是不可避免的,為此C++將強制類型轉換分為4種不同的類型,以提供更加安全可靠的轉換。

static_cast

用法:static_cast<type-id> (expression)

該運算符把expression轉換為type-id類型,但沒有運行時類型檢查來保證轉換的安全性。它主要有如下幾種用法:

(1)用於類層次結構中基類和派生類之間指針或引用的轉換。

進行上行轉換(把派生類的指針或引用轉換成基類表示)是安全的

進行下行轉換(把基類的指針或引用轉換為派生類表示),由於沒有動態類型檢查,所以是不安全的

(2)用於基本數據類型之間的轉換,如把int轉換成char。這種轉換的安全也要開發人員來保證

(3)把空指針轉換成目標類型的空指針

(4)把任何類型的表達式轉換為void類型

注意:static_cast不能轉換掉expression的const、volitale或者__unaligned屬性。主要用於基本類型之間、有繼承關係的類對象之間、類指針之間的轉換,不能用於基本類型指針之間的轉換。

比如:下面代碼第五行會報錯,「static_cast」: 無法從「float *」轉換為「int *」

const_cast

用法:const_cast<type-id> (expression)

該運算符用來修改類型的const或volatile屬性。除了const 或volatile修飾之外, type_id和expression的類型是一樣的。

常量指針被轉化成非常量指針,並且仍然指向原來的對象;

常量引用被轉換成非常量引用,並且仍然指向原來的對象;常量對象被轉換成非常量對象。


注意:用於去除變量的只讀屬性,強制轉換的目標類型必須是指針或引用


比如:下面代碼第二行會報錯,「const_cast」: 無法從「const int」轉換為「int」,值得注意的是,強轉去掉常量屬性之後通過指針修改變量,並不能改變原本常量的值,在【C++const常量玩出新花樣】中有講到

結果:

reinterpret_cast

用法:reinterpret_cast<type-id> (expression)

它可以把一個指針轉換成一個整數,也可以把一個整數轉換成一個指針(先把一個指針轉換成一個整數,在把該整數轉換成原類型的指針,還可以得到原先的指針值)。

該運算符的用法比較多。

該運算符平台移植性比價差。


注意:type-id必須是一個指針、引用、算術類型、函數指針或者成員指針。用於指針類型之間、整數和指針類型之間的轉換


比如:下面代碼第三行會報錯,「reinterpret_cast」: 無法從「float」轉換為「int」。

dynamic_cast

用法:dynamic_cast<type-id> (expression)該運算符把expression轉換成type_id類型的對象。type_id必須是類的指針、引用或者void*;如果type_id是類指針類型,那麼expression也必須是一個指針,如果type_id是一個引用,那麼expression也必須是一個引用。 dynamic_cast主要用於有繼承關係的類層次間的上行轉換和下行轉換,還可以用於類之間的交叉轉換。

在類層次間進行上行轉換時,dynamic_cast和static_cast的效果是一樣的;

在進行下行轉換時,dynamic_cast具有類型檢查的功能,比static_cast更安全。

#include <iostream>
using namespace std;
class parent
{
public:
        virtual void print()
        {
                cout << "parent" << endl;
        }
};

class son :public parent
{
public:
         void print()
        {
                cout << "son" << endl;
         }
         void printData()
         {
                 cout << "printData" << endl;
         }
};

int main()
{
        parent* ppParent = new son;  //調用是子類中與virtual 的同名函數
        ppParent->print();                   //調用是子類中與virtual 的同名函數
        son* ppSon = nullptr;
        if ((ppSon = dynamic_cast<son *>(ppParent)) != nullptr)
        {
                ppSon->print(); 
                ppSon->printData();
        }
        else
        {
                cout << "轉換失敗" << endl;
        }
        system("pause");
        return 0;
}

尾言

如果足下基礎比較差,不妨關注下人人都可以學習的視頻教程通俗易懂,深入淺出,一個視頻只講一個知識點。視頻不深奧,不需要鑽研,在公交、在地鐵、在廁所都可以觀看,隨時隨地漲姿勢的視頻教程


關鍵字: