C++類型轉換運算符詳解

老式顯式類型轉換

(類型)表達式 c風格的強制類型轉換

類型(表達式) 函數式的強制類型轉換

1,最開始使用的是c風格的類型轉換,但是為瞭能夠使類型轉換看起來更像是一個函數調用,因此引入瞭函數式的類型轉換。函數式的類型轉換能夠像使用一個函數那樣去進行轉換,比c風格的要更好一些。

2,一般來說,建議以上兩種類型轉換方式不要使用,改為使用以下四種類型轉換方式,如果你拒絕這個提議的話,那麼建議使用函數式的類型轉換方式。

c++的顯示類型轉換

舊式的類型轉換存在很多問題,因此,在c++中引入瞭新的類型轉換方式(當然,所謂新的也是幾十年前的事情瞭)。

static_cast

dynamic_cast

const_cast

reinterpret_cast

為什麼要有新的類型轉換

這裡主要存在兩個問題

第一,老式類型轉換沒有具體區分到底要怎麼轉換,是上面四種類型中的哪一種,或者哪幾種?好處是,比較方便,因為,使用老式類型轉換,你無需具體區分到底使用的是哪一種,隻要按照順序依次試一試能不能轉換就行瞭。壞處是,這種轉換是比較危險的,或者可能是用戶期望之外的。錯誤使用瞭類型轉換,但是卻沒有被發現,依然成功的被轉換瞭,這種行為會帶來更大的危害。

第二,老式類型轉換是比較難識別的,不管是c風格的也好,函數式的也好,都是隻用一個括號就可以瞭。括號顯然比起static_cast<>這樣的形式難以識別的多。因此,在復雜一些的表達式中,如果使用瞭多次類型轉換,我們甚至很難去把裡面所有的類型轉換全部找到,這也會造成很大的困擾。

具體應該使用哪種轉換

以前沒得選的時候,使用起來自然很容易,因為我們無需糾結使用哪種,直接用就行瞭。但是有瞭四種可供你選擇以後,這個問題就變的復雜起來瞭。到底應該用哪一種呢?什麼時候應該用什麼呢?當然,如果你實在分不清楚的話,那麼首先應該嘗試一下static_cast

static_cast運算符

static_cast<類型>(表達式)

static_cast最常用的情況是,類型和要轉換的內容之間可以發生隱式類型轉換

#include <iostream>
using namespace std;
int main()
{
	double a = 5 / 2;
	double b = static_cast<double>(5) / 2;
	// a的結果為2,b的結果為2.5
	cout << "a: " << a << endl;
	cout << "b: " << b << endl;
}

如果通過static_cast去轉換具有繼承關系的類,那麼向上或者向下轉換都是可以被允許的,但是轉換為無關的類型是不被允許的。

#include <iostream>
using namespace std;
int main()
{
	class A{};
	class B: public A{};
	class C{};
	A a;
	B b;
	C c;
	A * p1 = static_cast<A *>(&b); 
	B * p2 = static_cast<B *>(&a);
    // 轉換為無關類型是不被允許的
	// C * p3 = static_cast<C *>(&a);
}

dynamic_cast運算符

dynamic_cast<類型>(表達式)

dynamic_cast隻用於在繼承層級上進行轉換,可轉換的類型為指針類型或者引用類型。

如果轉換的類型為指針類型,且轉換失敗,那麼將返回空指針。

如果轉換的類型為引用類型,且轉換失敗,那麼會拋出std::bad_cast類型異常。

註意:static_cast也可以用於這種類型轉換,但是一般來說在處理dynamic_cast能解決的問題時,使用dynamic_cast要好於static_cast。

const_cast運算符

const_cast<類型>(表達式)

const_cast被用於移除或者添加cv限定符,當然主要是用於const

如果你還不知道cv限定符,那麼可以點擊這裡查看有關cv限定符的描述

#include <iostream>
using namespace std;
int main()
{	
	int a = 100;
	const int * p1 = &a;
	// 該賦值肯定是不被允許的
	// *p1 = 200
	// 該定義也是不被允許的,const int *類型不被允許用於初始化int * 
	// int * p2 = p1;
	// 使用const_cast類型轉換,將const int *類型轉換為int *類型
	int * p2 = const_cast<int *>(p1);
	*p2 = 200;
	cout << a << endl;
}

reinterpret_cast運算符

reinterpret_cast<類型>(表達式)

這是一種非常危險的轉換方式,它的功能是對類型進行重新解釋。也就是直接將表達式的內容,在底層層級上視為新類型。使用該運算符時應該非常謹慎小心。

老式顯式類型轉換實際的轉換方式

如果你使用瞭c風格或者函數式的顯式類型轉換,那麼將會依次做這樣的嘗試,直到遇到第一個轉換成功的選項為止。

const_cast

static_cast

static_cast const_cast

reinterpret_cast

reinterpret_cast const_cast

總結

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: