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


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

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

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

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

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

static_cast

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

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

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

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

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

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

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

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

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

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

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

const_cast

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

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

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

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


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


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

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

結果:

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

reinterpret_cast

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

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

該運算符的用法比較多。

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


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


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

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

dynamic_cast

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

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

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

<code>#include <iostream>
using namespace std;
class parent
{
public:
\tvirtual void print()
\t{
\t\tcout << "parent" << endl;
\t}
};

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

int main()

{
\tparent* ppParent = new son; //調用是子類中與virtual 的同名函數
\tppParent->print();\t\t\t//調用是子類中與virtual 的同名函數
\tson* ppSon = nullptr;
\tif ((ppSon = dynamic_cast(ppParent)) != nullptr)
\t{
\t\tppSon->print();
\t\tppSon->printData();
\t}
\telse
\t{
\t\tcout << "轉換失敗" << endl;
\t}
\tsystem("pause");
\treturn 0;
}
/<iostream>/<code>

尾言

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



分享到:


相關文章: