最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++實(shí)例講解四種類型轉(zhuǎn)換的使用

 更新時(shí)間:2022年06月13日 14:15:41   作者:你算哪一個(gè)bug?  
在C++語言中新增了四個(gè)關(guān)鍵字static_cast、const_cast、reinterpret_cast和dynamic_cast。這四個(gè)關(guān)鍵字都是用于類型轉(zhuǎn)換的,類型轉(zhuǎn)換(type cast),是高級(jí)語言的一個(gè)基本語法。它被實(shí)現(xiàn)為一個(gè)特殊的運(yùn)算符,以小括號(hào)內(nèi)加上類型名來表示,接下來讓我們一起來詳細(xì)了解

C++類型轉(zhuǎn)換

C語言風(fēng)格的轉(zhuǎn)換

C語言提供了自己的一套轉(zhuǎn)換規(guī)則,有好處也有壞處。

C語言的風(fēng)格:(type_name)expression;

C語言提供了隱式類型轉(zhuǎn)換和顯式類型轉(zhuǎn)換。顯式類型轉(zhuǎn)換一般也叫做強(qiáng)轉(zhuǎn),隱式類型轉(zhuǎn)換編譯器完成,如果轉(zhuǎn)換不了就報(bào)錯(cuò)。

而C語言類型轉(zhuǎn)換的風(fēng)格好處就是簡(jiǎn)單,缺陷比如轉(zhuǎn)換的可視性差,顯式類型轉(zhuǎn)換的寫法就只有一種,難以精準(zhǔn)的跟蹤錯(cuò)誤。

??char ch=1.1,char ch=1在.cpp下都是合法的,這就是隱式類型轉(zhuǎn)換,C語言下如果把一個(gè)結(jié)構(gòu)體給int就會(huì)報(bào)錯(cuò),因?yàn)榫幾g器不知道怎么去轉(zhuǎn),C++下可以通過實(shí)現(xiàn)operator int()實(shí)現(xiàn)類型轉(zhuǎn)換或者提供合適的構(gòu)造函數(shù)完成隱式類型轉(zhuǎn)換,下面以在.cpp中實(shí)現(xiàn)operator int()為例

下面這段代碼由于隱式類型轉(zhuǎn)換導(dǎo)致了死循環(huán)

C語言的類型轉(zhuǎn)換其實(shí)已經(jīng)足夠完成需求了,但是可視性不太好,比如你不能在代碼庫中搜索它(就一對(duì)括號(hào)怎么去搜索),所以C++提供了一套類型轉(zhuǎn)換,相當(dāng)于語法糖了,此外還會(huì)進(jìn)行一些編譯性檢查(比如dynamic_cast轉(zhuǎn)換失敗則返回空指針)。但其實(shí)作用都是一樣的。

C++風(fēng)格的類型轉(zhuǎn)換

C++標(biāo)準(zhǔn)為了增加類型轉(zhuǎn)換的可見性,提供了四種類型轉(zhuǎn)化的方式。

static_cast

靜態(tài)類型轉(zhuǎn)換,進(jìn)行相關(guān)類型的轉(zhuǎn)換,但不能轉(zhuǎn)換兩個(gè)不相關(guān)的類型(即編譯器看到這個(gè)轉(zhuǎn)換是行不通的就會(huì)報(bào)錯(cuò))。

static_cast < type-id > ( expression )

int main()
{
	double a = (int)5.5 + 5.3;//結(jié)果是10.3
	double b = static_cast <int>(5.5) + 5.3;
	cout << "a: " << a << endl;
	cout << "b: " << b << endl;
	return 0;
}

轉(zhuǎn)換不相關(guān)的類型:

reinterpret_cast

很暴力的一個(gè)操作符,由英文直譯過來就是重新解釋的轉(zhuǎn)型。白話就是將一段內(nèi)存重新解釋。

網(wǎng)上看到很多大佬的理解,這里借用或摻雜自己的思想:static_cast是做類型能做的轉(zhuǎn)換,不行編譯器就報(bào)錯(cuò),告訴你這樣是不合理的,reinterpret_cast則是就算不能轉(zhuǎn)換編譯器你也別報(bào)錯(cuò),我心里有數(shù)。由于reinterpret_cast本質(zhì)上是一個(gè)編譯器指令,所以實(shí)際動(dòng)作完全取決于編譯器,失去了移植性。

暴力歸暴力,但也是合理范圍內(nèi)的,比如你把一個(gè)結(jié)構(gòu)體硬塞給int肯定是不行的,但是把結(jié)構(gòu)體指針重新解釋為int那是一點(diǎn)問題沒有。

此外reinterpret_cast重新解釋的辦法是把那一塊內(nèi)存的比特位全部復(fù)制下來重新解釋。

下面的例子把一個(gè)結(jié)構(gòu)體指針解釋為int再加上5.3。

struct Test
{
	int a;
};
int main()
{
	Test* t = new Test;
	double c = reinterpret_cast <int>(&t) + 5.3;
	cout << c << endl;
	return 0;
}

const_cast

刪除變量的const屬性,一般和指針或引用連用

int main()
{
	const int a = 1;//a是常變量,在棧上
	int* p = const_cast<int*>(&a);
	*p = 2;
	cout << a << endl;
	cout << *p << endl;
	return 0;
}

volatile const int a=1;//打印的a就會(huì)是2

volatile后編譯器對(duì)訪問該變量的代碼不再優(yōu)化。比如上面那句代碼打印1就是因?yàn)榫幾g器優(yōu)化,讀取的a是從寄存器中讀取的,而不是內(nèi)存。

多線程中也有很多關(guān)于 volatile的應(yīng)用。

dynamic_cast

dynamic_cast,安全的向下轉(zhuǎn)型。

多態(tài)的轉(zhuǎn)換中向下轉(zhuǎn)型(父類轉(zhuǎn)為子類)用dynamic是安全的,但是父類必須有虛函數(shù),否則編譯報(bào)錯(cuò),且只能用于指針或引用。

向上轉(zhuǎn)型,子類給父類,發(fā)生切割,不需要轉(zhuǎn)換。

向下轉(zhuǎn)型,父類地址給子類指針,需要類型轉(zhuǎn)換,由于是類型是子類指針,但是給的地址是父類的,如果用指針去訪問子類獨(dú)有的數(shù)據(jù)可能就會(huì)造成越界,然后程序就可能崩了,所以此時(shí)就需要dynamic_cast進(jìn)行轉(zhuǎn)換了,因?yàn)閐ynamic_cast會(huì)檢查父類指針是否指向的是這個(gè)子類,如果是父類說明可能帶來一些安全問題,會(huì)轉(zhuǎn)換失敗返回空指針,反之則實(shí)現(xiàn)轉(zhuǎn)換。

理解向下轉(zhuǎn)型不安全有個(gè)例子:男人是人,但人不一定是男人(男人派生自人,男人的指針=(男人類型的指針強(qiáng)轉(zhuǎn))人的地址,此時(shí)如果通過男人指針去調(diào)用男人自己獨(dú)有的特性就是越界,因?yàn)閷?shí)際上拿到的是人的地址,并沒有存儲(chǔ)男人的特性,也可以從空間大小上來解釋,人是父類,空間更小,男人是子類,空間更大,給的是小空間,卻有了訪問大空間的能力,所以可能造成越界,所以是不安全的)

此外在一個(gè)父類有多個(gè)子類且需要類型轉(zhuǎn)換時(shí),dynamic_cast也能起到作用,舉個(gè)例子

//父類是Entity,子類是Player和Enemy, e,player,enemy分別表示他們對(duì)應(yīng)的實(shí)例化對(duì)象
Entity* p=&player;
Enemy* p1=(Enemy*)p;//向下轉(zhuǎn)型需要強(qiáng)轉(zhuǎn),這樣搞就出問題了,p明明指向的是一個(gè)player,現(xiàn)在類型為Enemy的指針居然指向了一個(gè)Player的對(duì)象,如果對(duì)其內(nèi)存進(jìn)行了操作,那后果是不可預(yù)料的。

父類指針一開始指向一個(gè)父類對(duì)象,再給到子類類型的指針,存在越界的風(fēng)險(xiǎn),如果為了保證安全則需要檢查。

父類的指針指向子類對(duì)象(向上轉(zhuǎn)型),再給到子類指針,合理。

所以建議使用dynamic_cast,因?yàn)榭梢员WC安全, 轉(zhuǎn)換失敗返回空指針(NULL)。

dynamic_cast的底層與RTTI有關(guān),借助RTTI拿到類型信息,所以dynamic_cast更像一個(gè)函數(shù),因?yàn)椴皇蔷幾g指令,所以會(huì)帶來一些性能的損失。

RTTI 是“Runtime Type Information”的縮寫,意思是運(yùn)行時(shí)類型信息。RTTI存儲(chǔ)了所有類型運(yùn)行時(shí)的類型信息,增加了開銷但是可以讓我們做更多的操作。dynamic_cast的底層就是借助了RTTI+匹配,具體的不太了解。VS可以關(guān)閉RTTI,但是也就不能用dynamic_cast了

下面給一個(gè)代碼例子

class Entity
{
public:
	virtual void Print() {};//dynamic_cast使用的前提必須是父類有虛函數(shù)
};
class Player:public Entity
{
};
class Enemy :public Entity
{
};
void Check(void* p)
{
	if (p)
	{
		cout << "轉(zhuǎn)換成功" << endl;
	}
	else
	{
		cout << "轉(zhuǎn)換失敗" << endl;
	}
}
int main()
{
	Entity* e = new Entity();
	Entity* actuallyPlayer = new Player();//向上轉(zhuǎn)型
	//安全的向下轉(zhuǎn)型
	Player* player =(Player*)actuallyPlayer;//向下轉(zhuǎn)型需要轉(zhuǎn)換類型
	Player* player2 = dynamic_cast<Player*>(actuallyPlayer);
	Check(player2); cout << endl;
	//不安全的向下轉(zhuǎn)型
	Player* player3 = (Player*)e;
	Player* player4 = dynamic_cast<Player*>(e);
	Check(player4); cout << endl;
	Entity* actuallyEnemy = new Enemy();
	Player* player5 = dynamic_cast<Player*>(actuallyEnemy);
	Check(player5); cout << endl;
	return 0;
}

dynamic也常常利用返回值是否是空指針來判斷指針具體指向誰。

用dynamic_cast的地方其實(shí)也可以用static_cast,不過static_cast不會(huì)進(jìn)行安全檢查,如果你很清楚其指向,并且在安全的前提下,為了減少程序開銷那可以考慮用static_cast

小結(jié)

  • static_cast用于相關(guān)類型的轉(zhuǎn)換
  • reinterpret_cast用于重新解釋內(nèi)存(很暴力,用的時(shí)候心里要有數(shù))
  • const_cast常用來取出const屬性,常與指針連用來修改const變量的值
  • dynamic_cast,在多態(tài)里提供安全的向下轉(zhuǎn)換(轉(zhuǎn)換不安全就返回空指針,只要對(duì)返回的指針進(jìn)行判斷我們就能知道此次轉(zhuǎn)換安不安全了)

到此這篇關(guān)于C++實(shí)例講解四種類型轉(zhuǎn)換的使用的文章就介紹到這了,更多相關(guān)C++類型轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)

    C++實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • C/C++中比較字符串的方法詳解

    C/C++中比較字符串的方法詳解

    這篇文章主要介紹了C/C++中比較字符串的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • c++中的自增/自減操作方式

    c++中的自增/自減操作方式

    這篇文章主要介紹了C++中的自增和自減運(yùn)算符,包括前綴和后綴形式,并通過一個(gè)具體的例子解釋了自增/自減表達(dá)式的值與函數(shù)參數(shù)傳遞的關(guān)系,文章指出,自增/自減表達(dá)式的值是在表達(dá)式求值時(shí)確定的,而不是在自增/自減運(yùn)算后
    2025-03-03
  • C語言計(jì)算大數(shù)相加的方法

    C語言計(jì)算大數(shù)相加的方法

    這篇文章主要為大家詳細(xì)介紹了C語言計(jì)算大數(shù)相加的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • 使用設(shè)計(jì)模式中的單例模式來實(shí)現(xiàn)C++的boost庫

    使用設(shè)計(jì)模式中的單例模式來實(shí)現(xiàn)C++的boost庫

    這篇文章主要介紹了使用設(shè)計(jì)模式中的單例模式來實(shí)現(xiàn)C++的boost庫的方法,其中作者對(duì)線程安全格外強(qiáng)調(diào),需要的朋友可以參考下
    2016-03-03
  • C++關(guān)鍵字mutable學(xué)習(xí)筆記

    C++關(guān)鍵字mutable學(xué)習(xí)筆記

    這篇文章主要為大家介紹了C++關(guān)鍵字mutable學(xué)習(xí)筆記,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • C語言中pthread_exit和pehread_join的使用

    C語言中pthread_exit和pehread_join的使用

    pthread_exit用于強(qiáng)制退出一個(gè)線程,pthread_join用于阻塞等待線程退出,獲取線程退出狀態(tài),本文主要介紹了C語言中pthread_exit和pehread_join函數(shù)的使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • C++實(shí)現(xiàn)std::set的示例項(xiàng)目

    C++實(shí)現(xiàn)std::set的示例項(xiàng)目

    std::set是C++標(biāo)準(zhǔn)庫中的關(guān)聯(lián)容器,提供有序唯一元素集合,本文就來介紹一下std::set的具體使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-02-02
  • C++實(shí)現(xiàn)一個(gè)簡(jiǎn)易版的事件(Event)的示例代碼

    C++實(shí)現(xiàn)一個(gè)簡(jiǎn)易版的事件(Event)的示例代碼

    之前在?windows系統(tǒng)中開發(fā)應(yīng)用時(shí),?遇到需要進(jìn)行線程同步的時(shí)候幾乎都是使用的事件內(nèi)核對(duì)象?Event。本文為大家整理了C++實(shí)現(xiàn)一個(gè)簡(jiǎn)易版的事件(Event)的相關(guān)資料,需要的可以參考一下
    2022-11-11
  • 概述C++中的 public protected private friend關(guān)鍵字的用法

    概述C++中的 public protected private friend關(guān)鍵字的用法

    這篇文章簡(jiǎn)要概述了C++中的 public protected private friend關(guān)鍵字的用法,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起學(xué)習(xí)吧
    2016-08-08

最新評(píng)論

肇东市| 依安县| 临漳县| 海林市| 搜索| 尼玛县| 海晏县| 大埔区| 日土县| 十堰市| 郎溪县| 葫芦岛市| 娱乐| 黄冈市| 桐乡市| 建水县| 集贤县| 惠东县| 伽师县| 湖州市| 罗江县| 大厂| 大丰市| 通城县| 达孜县| 广平县| 商水县| 定安县| 东莞市| 宜黄县| 伊川县| 监利县| 乐业县| 宜良县| 台北市| 广昌县| 承德县| 神池县| 平山县| 萝北县| 扎兰屯市|