關(guān)于C++的強(qiáng)制類(lèi)型轉(zhuǎn)換淺析
前言
一說(shuō)起強(qiáng)制類(lèi)型轉(zhuǎn)換大家都很熟悉,相信很多學(xué)習(xí)完C++的朋友還在使用C語(yǔ)言的強(qiáng)制類(lèi)型的方式 (類(lèi)型)變量.
C++其實(shí)也具有自己的一套強(qiáng)制類(lèi)型轉(zhuǎn)換它們分明是:static_cast reinterpret_cast const_cast dynamic_cast四種類(lèi)型.
那么肯定會(huì)有人好奇C++是不是閑,C語(yǔ)言的強(qiáng)制類(lèi)型用的舒舒服服的,為什么要新推出來(lái)這幾個(gè)?
新類(lèi)型的強(qiáng)制轉(zhuǎn)換可以提供更好的控制強(qiáng)制轉(zhuǎn)換過(guò)程,允許控制各種不同種類(lèi)的強(qiáng)制轉(zhuǎn)換。C++中風(fēng)格是static_cast<type>。C++風(fēng)格的強(qiáng)制轉(zhuǎn)換其他的好處是,它們能更清晰的表明它們要干什么。程序員只要掃一眼這樣的代碼,就能立即知道一個(gè)強(qiáng)制轉(zhuǎn)換的目
的。
static_cast
static_cast用于非多態(tài)類(lèi)型的轉(zhuǎn)換(靜態(tài)轉(zhuǎn)換),任何標(biāo)準(zhǔn)轉(zhuǎn)換都可以用它,但它不能用于兩個(gè)不相關(guān)的類(lèi)型進(jìn)行轉(zhuǎn)換.
何為不相關(guān)類(lèi)型? 比如int 和 double char short就是相關(guān)類(lèi)型. 和int*就是不相關(guān)類(lèi)型.
我們來(lái)看一看static_cast的用法. 例如,通過(guò)將一個(gè)運(yùn)算對(duì)象強(qiáng)制轉(zhuǎn)換成double類(lèi)型就能使表達(dá)式執(zhí)行浮點(diǎn)數(shù)除法:
double slope = static_cast<double>(j) / i;
當(dāng)static_cast需要把一個(gè)較大的算術(shù)類(lèi)型賦值給較小的類(lèi)型時(shí),static_cast非常有用。此時(shí),強(qiáng)制類(lèi)型轉(zhuǎn)換告訴程序的讀者和編譯器:我們知道并且不在乎潛在的精度損失。一般來(lái)說(shuō),如果編譯器發(fā)現(xiàn)一個(gè)的算術(shù)類(lèi)型試圖賦值給較小的類(lèi)型,就會(huì)給出警告信息;但是當(dāng)我們執(zhí)行了顯式的類(lèi)型轉(zhuǎn)換后,警告信息就會(huì)被關(guān)閉了。
reinterpret_cast
reinterpret_cast有著和C風(fēng)格的強(qiáng)制轉(zhuǎn)換同樣的能力。它可以轉(zhuǎn)化任何內(nèi)置的數(shù)據(jù)類(lèi)型為其他任何的數(shù)據(jù)類(lèi)型,也可以轉(zhuǎn)化任何指針類(lèi)型為其他的類(lèi)型。它甚至可以轉(zhuǎn)化內(nèi)置的數(shù)據(jù)類(lèi)型為指針,無(wú)須考慮類(lèi)型安全或者常量的情形。不到萬(wàn)不得已絕對(duì)用。
因?yàn)閞einterpret_cast是一個(gè)蠻bug的操作,下面我來(lái)演示一下.
typedef void (* FUNC)();
int DoSomething (int i)
{
cout<<"DoSomething" <<endl;
return 0;
}
void Test ()
{
// reinterpret_cast可以編譯器以FUNC的定義方式去看待 DoSomething函數(shù)
// 所以非常的BUG,下面轉(zhuǎn)換函數(shù)指針的代碼是不可移植的,所以不建議這樣用
// C++不保證所有的函數(shù)指針都被一樣的使用,所以這樣用有時(shí)會(huì)產(chǎn)生不確定的結(jié)果
FUNC f = reinterpret_cast< FUNC>(DoSomething );
f();
}
當(dāng)你這樣運(yùn)行的時(shí)候,你會(huì)發(fā)現(xiàn)通過(guò)函數(shù)指針沒(méi)有傳參數(shù)調(diào)用這個(gè)有參數(shù)的函數(shù)居然可以調(diào)用,這就很尷尬了,所以我告訴你不到萬(wàn)不得已就不要使用reinterpret_cast
const_cast
對(duì)于將常量對(duì)象轉(zhuǎn)化為非常量對(duì)象的行為,我們一般稱(chēng)之為“去掉const性質(zhì)”。一旦我們?nèi)サ袅四硞€(gè)對(duì)象的const性質(zhì),編譯器就不再阻止我們對(duì)該對(duì)象進(jìn)行寫(xiě)操作了。如果對(duì)象本身不是一個(gè)常量,使用強(qiáng)制類(lèi)型轉(zhuǎn)換獲得寫(xiě)權(quán)限是合法的行為。然而如果對(duì)象是一個(gè)常量,再使用const_cast執(zhí)行寫(xiě)操作就會(huì)產(chǎn)生未定義的后果。
舉個(gè)例子:
#include<iostream>
#include<Windows.h>
#include<assert.h>
using namespace std;
int main()
{
const int a = 2;
int *p = const_cast<int*>(&a);
*p = 3;
cout << a << endl;
system("pause");
return 0;
}
我們有理由的認(rèn)為在內(nèi)存當(dāng)中a的值被修改為3,但是結(jié)果呢? 我們來(lái)看一看

這不科學(xué)???? 我們?cè)俅蜷_(kāi)監(jiān)視窗口看一下a的值.

我們都知道監(jiān)視窗口看到的都是從內(nèi)存當(dāng)中拿到的,但是為什么內(nèi)存當(dāng)中為3,打印出來(lái)就是2呢? 我來(lái)解釋一下.
C++編譯器具有優(yōu)化功能,當(dāng)你定一個(gè)const的常量的時(shí)候,系統(tǒng)覺(jué)得它不會(huì)被改變了,于是做一個(gè)優(yōu)化把該常量存到寄存器當(dāng)中,下次訪問(wèn)的過(guò)程更快速一點(diǎn). 所以當(dāng)顯示窗口讀取數(shù)據(jù)的時(shí)候,他會(huì)直接去寄存器當(dāng)中讀取數(shù)據(jù).而不是去內(nèi)存,所以導(dǎo)致我們明明該掉了a的值,卻打印不出來(lái),但是如何解決這個(gè)問(wèn)題呢??
c++有一個(gè)關(guān)鍵字: volatile 該關(guān)鍵字的作用防止編譯器優(yōu)化,這個(gè)時(shí)候要輸出a就會(huì)老老實(shí)實(shí)的回內(nèi)存去查看.
#include<iostream>
#include<Windows.h>
#include<assert.h>
using namespace std;
int main()
{
volatile const int a = 2;
int *p = const_cast<int*>(&a);
*p = 3;
cout << a << endl;
system("pause");
return 0;
}
dynamic_cast
前三種的強(qiáng)制類(lèi)型轉(zhuǎn)換,他們能做到的C語(yǔ)言的強(qiáng)制類(lèi)型轉(zhuǎn)換也大多能做到,最后一種C語(yǔ)言的強(qiáng)制類(lèi)型轉(zhuǎn)換就沒(méi)有辦法了.
在類(lèi)的轉(zhuǎn)換時(shí),在類(lèi)層次間進(jìn)行上行轉(zhuǎn)換時(shí),dynamic_cast和static_cast的效果是一樣的。在進(jìn)行下行轉(zhuǎn)換時(shí),dynamic_cast具有類(lèi)型檢查的功能,比static_cast更安全。當(dāng)用于多態(tài)類(lèi)型時(shí),它允許任意的隱式類(lèi)型轉(zhuǎn)換以及相反過(guò)程. 不過(guò),與static_cast不同,在后一種情況里(注:即隱式轉(zhuǎn)換的相反過(guò)程),dynamic_cast 會(huì)檢查操作是否有效. 也就是說(shuō), 它會(huì)檢查轉(zhuǎn)換是否會(huì)返回一個(gè)被請(qǐng)求的有效的完整對(duì)象。檢測(cè)在運(yùn)行時(shí)進(jìn)行. 如果被轉(zhuǎn)換的指針不是一個(gè)被請(qǐng)求的有效完整的對(duì)象指針,返回值為NULL. 對(duì)于引用 類(lèi)型,會(huì)拋出bad_cast異常
你說(shuō)這個(gè)強(qiáng)轉(zhuǎn)有啥用,其實(shí)對(duì)于我這種菜鳥(niǎo)還真的沒(méi)用過(guò),不過(guò)我知道一個(gè)問(wèn)題可以使用這樣的方法解決. 給你兩個(gè)類(lèi)讓你分辨那個(gè)是子類(lèi)那個(gè)是父類(lèi),我們來(lái)看看是如何解決的.
#include<iostream>
#include<Windows.h>
#include<assert.h>
using namespace std;
class AA
{
public:
virtual void fun1()
{
cout << "hehe" << endl;
}
public:
int a;
};
class BB :public AA
{
public:
virtual void fun1()
{
cout << "heh2e" << endl;
}
public:
int c;
};
int main()
{
AA* q = new AA();
BB* p = new BB();
AA* a;
BB* b;
b = dynamic_cast<BB*>(q);
if (b == NULL)
{
cout << "AA為基類(lèi)" << endl;
}
else{
cout << "AA為子類(lèi)" << endl;
}
a = dynamic_cast<AA*>(p);
if (a == NULL)
{
cout << "BB為基類(lèi)" << endl;
}
else
{
cout << "BB為子類(lèi)" << endl;
}
system("pause");
return 0;
}
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- C++強(qiáng)制類(lèi)型轉(zhuǎn)換的四種方式
- 解析C++中四種強(qiáng)制類(lèi)型轉(zhuǎn)換的區(qū)別詳解
- 基于c++強(qiáng)制類(lèi)型轉(zhuǎn)換的(總結(jié))詳解
- C++中4種強(qiáng)制類(lèi)型轉(zhuǎn)換的區(qū)別總結(jié)
- C++超詳細(xì)講解強(qiáng)制類(lèi)型轉(zhuǎn)換
- 深入C++四種強(qiáng)制類(lèi)型轉(zhuǎn)換的總結(jié)
- C++ 強(qiáng)制類(lèi)型轉(zhuǎn)換詳解
- 淺談C++的語(yǔ)句語(yǔ)法與強(qiáng)制數(shù)據(jù)類(lèi)型轉(zhuǎn)換
- C++強(qiáng)制類(lèi)型轉(zhuǎn)換詳細(xì)示例代碼
相關(guān)文章
C++ main函數(shù)的幾點(diǎn)細(xì)節(jié)
這篇文章主要介紹了C++ main函數(shù)的幾點(diǎn)細(xì)節(jié),幫助大家更好的理解和學(xué)習(xí)C++,感興趣的朋友可以了解下2020-08-08
C語(yǔ)言實(shí)現(xiàn)AT指令A(yù)SCII碼的拼接處理流程
今天小編就為大家分享一篇關(guān)于C語(yǔ)言實(shí)現(xiàn)AT指令A(yù)SCII碼的拼接處理流程,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12
C++實(shí)現(xiàn) vector 的四則運(yùn)算
本文給大家介紹的是在C++中實(shí)現(xiàn)高效的vector四則運(yùn)算的方法的相關(guān)資料,需要的朋友可以參考下2016-07-07
c++中的單例類(lèi)模板的實(shí)現(xiàn)方法詳解
這篇文章主要介紹了c++中的單例類(lèi)模板的實(shí)現(xiàn)方法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
用C++實(shí)現(xiàn)一個(gè)鏈?zhǔn)綏5膶?shí)例代碼
本篇文章是對(duì)使用C++實(shí)現(xiàn)一個(gè)鏈?zhǔn)綏5拇a進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
C++ STL入門(mén)教程(2) list雙向鏈表使用方法(附程序代碼)
這篇文章主要為大家詳細(xì)介紹了C++ STL入門(mén)教程第二篇,list雙向鏈表使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
詳解C語(yǔ)言實(shí)現(xiàn)空間索引四叉樹(shù)
本文主要介紹了用C語(yǔ)言實(shí)現(xiàn)四叉樹(shù),對(duì)算法感興趣的同學(xué),可以參考下,并且試驗(yàn)一下。2021-05-05

