C++類型轉(zhuǎn)換詳解
C++對(duì)于內(nèi)置類型有隱式或顯式的類型轉(zhuǎn)化,如int,double,long,char,但是,C++還有類這個(gè)概念,類是一種自定義類型,為了讓類(自定義類型)達(dá)到內(nèi)置類型的層次,C++對(duì)類也挺提供一些方法進(jìn)行自動(dòng)或者強(qiáng)制類型轉(zhuǎn)換
C++的好多工作,在我看來(lái)就是讓自定義類型能和內(nèi)置類型一樣簡(jiǎn)單使用、操作。
內(nèi)置類型的轉(zhuǎn)換
int a = 8; double b = 4.4; long c = a;//隱式類型轉(zhuǎn)換 long d = (long)b;//顯式類型轉(zhuǎn)換
這都是我們熟悉的,是編譯器已經(jīng)幫我們處理好了的。
自定義類型轉(zhuǎn)換
對(duì)于自定義類型,其類型轉(zhuǎn)換,都是我們可以自己實(shí)現(xiàn),自己控制的。
/* * 對(duì)石塊類的 聲明定義 */ class Stone { public: Stone(double weight); Stone(int stone_type, double volume); private: int _stone_type; double _weight; double _volume; }; Stone::Stone(double weight) { _stone_type = 1; _weight = weight; _volume = 10.5; } Stone::Stone(int stone_type, double volume=10.5) { _stone_type = stone_type; _weight = 5.8; _volume = volume; }
我們提供了Stone(double) 這個(gè)構(gòu)造函數(shù)的重載,可以直接將double類型進(jìn)行構(gòu)造出一個(gè)類。
Stone s1 = 24.5; Stone s2(10.5); Stone s3(21, 20.5);
對(duì)于Stone s1 = 24.5;而言,重新是由構(gòu)造函數(shù)Stone(double)來(lái)創(chuàng)建一個(gè)臨時(shí)的Stone對(duì)象,并將24.5作為初始值,隨后,采用逐成員復(fù)值的方法,將該臨時(shí)對(duì)象的內(nèi)容復(fù)制到s1對(duì)象中。也就是將一個(gè)double類型的對(duì)象轉(zhuǎn)換為Stone類型的對(duì)象。
這一過(guò)程稱為隱式轉(zhuǎn)換,它是自動(dòng)進(jìn)行的,不需要顯式遷至類型轉(zhuǎn)換。
注意:只有接受一個(gè)參數(shù)的構(gòu)造函數(shù)才能作為轉(zhuǎn)換函數(shù),
像Stone(int stone_type, double volume)有兩個(gè)參數(shù),因此不能用來(lái)轉(zhuǎn)換類型,然而,如果它第二代參數(shù)是個(gè)缺省,提供了默認(rèn)值,其便可以用來(lái)進(jìn)行int對(duì)象的轉(zhuǎn)換。
這個(gè)轉(zhuǎn)換函數(shù)是將那些其他(內(nèi)置或者其他的類型)類型向類類型轉(zhuǎn)換
explicit 關(guān)鍵字
將構(gòu)造函數(shù)用作于自動(dòng)類型轉(zhuǎn)換函數(shù)似乎是一項(xiàng)不錯(cuò)的特性,但是這種自動(dòng)轉(zhuǎn)換的并不是在所有情況下都需要,某些情況下,不需要這種轉(zhuǎn)換,但是卻意外的進(jìn)行了轉(zhuǎn)換。
所以C++提供了關(guān)鍵字explicit,用于關(guān)閉這種自動(dòng)轉(zhuǎn)換。
explicit的意思是:顯式的,明確的。
可以加在函數(shù)聲明前
explicit Stone(double weight)
這樣,只能顯式調(diào)用這個(gè)構(gòu)造。
Stone s1 = Stone(24.5); Stone s4 = (Stone)19.99;//非常像內(nèi)置類型的顯式轉(zhuǎn)換
這樣顯式調(diào)用就沒(méi)什么問(wèn)題。
提醒
還有一個(gè)要提醒的:如果像這個(gè)一樣,
有兩個(gè)參數(shù)的函數(shù),
有一個(gè)加了explicit,另一個(gè)沒(méi)加,如果還像剛才一樣,隱式轉(zhuǎn)換的那種,還是能泡過(guò)的,因?yàn)?,?huì)執(zhí)行兩個(gè)參數(shù)的構(gòu)造函數(shù),因?yàn)榫瓦@個(gè)是能匹配的,這肯會(huì)造成一個(gè)隱患,給大家提個(gè)醒,要加explicit,構(gòu)成重載的函數(shù)最好都加上,不然出來(lái)Bug就不好找了。
提問(wèn):編譯器在什么時(shí)候使用Stone(double)?
如果在聲明中使用了關(guān)鍵字explicit,則Stone(double)將只能用于顯式強(qiáng)制類型轉(zhuǎn)換,
如果沒(méi)有的話,就還能用于隱式類型轉(zhuǎn)換
- 將Stone對(duì)象初始化為double值時(shí),例:Stone s1 = 24.5;
- double值賦給Stone對(duì)象,例:Stone s5;s5 = 19.7;
- 將double值傳遞給接受Stone參數(shù)的函數(shù),例:
void Print(const Stone& tmp) {cout << "Print" << endl;} Print(19.7);
- 返回值被聲明為Stone類型的函數(shù)試圖返回double。
- 在上述任意一種情況下,使用可轉(zhuǎn)換為double類型的內(nèi)置類型時(shí)(只要能轉(zhuǎn)換成double類型的內(nèi)置類型對(duì)象,都能這樣隱式調(diào)用)
Stone s5; s5 = 19; Stone s6(100);
同時(shí),要記住編譯器不能處理具有二義性的調(diào)用。
轉(zhuǎn)換函數(shù)
概念介紹
上面也介紹過(guò)轉(zhuǎn)換函數(shù),
不過(guò)那是內(nèi)置類型轉(zhuǎn)換為類類型,
這里的是類類型轉(zhuǎn)換為內(nèi)置類型。
轉(zhuǎn)換函數(shù)的形式:operator typeName();
1.轉(zhuǎn)換函數(shù)必須是類方法
2.轉(zhuǎn)換函數(shù)不能指定返回類型
3.轉(zhuǎn)換函數(shù)不能有參數(shù)
例如:轉(zhuǎn)換為double類型的函數(shù)原型:
operator double();
typeName
(這里指 double ,因此就不需要指定返回類型。轉(zhuǎn)換函數(shù)是類方法意味著:它需要類對(duì)象來(lái)調(diào)用,從而告知函數(shù)要轉(zhuǎn)換的值。因此,函數(shù)不需要函數(shù)。
Stone::operator double() const { return _weight; } Stone s4 = (Stone)19.99; double d1 = s4;//隱式調(diào)用 double d2 = (double)s4;//顯式 double d3 = double(s4);//顯式
且這調(diào)用的都是轉(zhuǎn)換函數(shù)。
自動(dòng)引用類型轉(zhuǎn)換
像
double d1 = s4;//隱式調(diào)用
都是自動(dòng)轉(zhuǎn)換。
還有賦值的情況,可能會(huì)存在內(nèi)置類型之間的轉(zhuǎn)換。
long l1 = s4;
這里可沒(méi)有l(wèi)ong的轉(zhuǎn)換函數(shù),說(shuō)明是轉(zhuǎn)化為double后,又轉(zhuǎn)換為了long類型。
缺陷
轉(zhuǎn)換函數(shù)都存在缺陷。
提供自動(dòng)調(diào)用、隱式轉(zhuǎn)換的函數(shù)存在的問(wèn)題:使用者不希望轉(zhuǎn)換時(shí),轉(zhuǎn)換函數(shù)也可能進(jìn)行了轉(zhuǎn)換。
所以最好還是要加上explicit
,只有顯式調(diào)用時(shí),才能進(jìn)行轉(zhuǎn)換。
或者,使用一些功能相同的類方法來(lái)繼續(xù)代替,這樣,如果類成員又類型一樣的也能轉(zhuǎn)換。
double Stone::Stone_to_double_weight(void) { return _weight; } double Stone::Stone_to_double_volume(void) { return _volume; }
我覺(jué)得這玩意比那個(gè)還好用一些。
總結(jié)
應(yīng)謹(jǐn)慎使用隱式轉(zhuǎn)換函數(shù)。通常,最好選擇僅在被顯式調(diào)用時(shí)才會(huì)執(zhí)行的函數(shù)
C++為類提供了下面的類型轉(zhuǎn)換
- 只有一個(gè)參數(shù)的類構(gòu)造函數(shù)用于將類型與該參數(shù)相同的值轉(zhuǎn)換為類類型。
- 被稱為轉(zhuǎn)換函數(shù)的特殊類成員運(yùn)算符函數(shù),用于將類對(duì)象轉(zhuǎn)換為其他類型,轉(zhuǎn)換函數(shù)是類成員,沒(méi)有返回類型,沒(méi)有參數(shù),名為
operator typeName();
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Visual Studio2022+QT6創(chuàng)建桌面應(yīng)用實(shí)現(xiàn)
本文主要介紹了Visual Studio2022+QT6創(chuàng)建桌面應(yīng)用實(shí)現(xiàn),文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-02-02C語(yǔ)言中輸入函數(shù)(scanf()、fgets()和gets())的區(qū)別詳解
這篇文章主要給大家介紹了關(guān)于C語(yǔ)言中三種輸入函數(shù)(scanf()、fgets()和gets())區(qū)別的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11C語(yǔ)言大作業(yè)之圖書(shū)管理系統(tǒng)的實(shí)現(xiàn)詳程
隨著網(wǎng)絡(luò)技術(shù)的高速發(fā)展,計(jì)算機(jī)應(yīng)用的普及,利用計(jì)算機(jī)對(duì)圖書(shū)館的日常工作進(jìn)行管理勢(shì)在必行,趁著寒假時(shí)間手把手帶你用C語(yǔ)言實(shí)現(xiàn)一個(gè)圖書(shū)管理系統(tǒng),大家可以在過(guò)程中查缺補(bǔ)漏,提升水平2022-01-01C語(yǔ)言實(shí)現(xiàn)注冊(cè)登錄系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)注冊(cè)登錄系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12簡(jiǎn)單談?wù)凜++ 頭文件系列之(iosfwd)
本文給大家分享的是小編關(guān)于頭文件系列的(iosfwd)的簡(jiǎn)單講解,所謂iosfwd,其實(shí)就是“input output stream forward”,下面我們來(lái)詳細(xì)看看2017-02-02C++內(nèi)存對(duì)齊的實(shí)現(xiàn)
本文主要介紹了C++內(nèi)存對(duì)齊的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02