c++類的隱式轉(zhuǎn)換與強制轉(zhuǎn)換重載詳解
在寫這篇文章之前,讓我們先回顧一下編譯器通過匹配過程確定調(diào)用哪一個函數(shù)的匹配順序:
(1)尋找和使用最符合函數(shù)名和參數(shù)類型(包括返回值)的函數(shù),若找到則調(diào)用;
(2)否則,尋找一個函數(shù)模板,將其實例化產(chǎn)生一個匹配的重載函數(shù),若找到則調(diào)用;
(3)否則,尋找可以通過類型轉(zhuǎn)換進(jìn)行參數(shù)匹配的重載函數(shù),若找到則調(diào)用它。
如果以上步驟均未找到匹配函數(shù),則這個調(diào)用是錯誤的;如果這個調(diào)用有多于一個的匹配選譯,則調(diào)用匹配出現(xiàn)二義性,也是錯誤的。
類型轉(zhuǎn)換是將一種類型的值映射為另一種類型的值。類型轉(zhuǎn)換實際上包含有自動隱含和強制的兩種。
C語言編譯系統(tǒng)提供的內(nèi)部數(shù)據(jù)類型的自動隱式轉(zhuǎn)換規(guī)則如下:
1.程序在執(zhí)行算術(shù)運算時,低類型可以轉(zhuǎn)換為高類型。
2.在賦值表達(dá)式中,右邊表達(dá)式的值自動隱式轉(zhuǎn)換為左邊變量的類型,并賦值給它。
3.當(dāng)在函數(shù)調(diào)用時,將實參值賦給形參,系統(tǒng)隱式地將實參轉(zhuǎn)換為形參的類型后,賦給形參。
4.函數(shù)有返回值時,系統(tǒng)將自動地將返回表達(dá)式類型轉(zhuǎn)換為函數(shù)類型后,賦值給調(diào)用函數(shù)。
在以上情況下,系統(tǒng)會進(jìn)行隱式轉(zhuǎn)換的。當(dāng)在程序中發(fā)現(xiàn)兩個數(shù)據(jù)類型不相容時,又不能自動完成隱式轉(zhuǎn)換,則將出現(xiàn)編譯錯誤。例如:
int* p = 100;
在這種情況下,編譯程序?qū)箦e,為了消除錯誤,可以進(jìn)行如下所示的強制類型轉(zhuǎn)換:
int* p = (int *)100;
將整型數(shù)100顯式地轉(zhuǎn)換成指針類型。
構(gòu)造函數(shù)具有類型轉(zhuǎn)換功能
在實際應(yīng)用中,當(dāng)類定義中提供了單個參數(shù)的構(gòu)造函數(shù)時,該類便提供了一種將其他數(shù)據(jù)類型的數(shù)值或變量轉(zhuǎn)換為用戶所定義數(shù)據(jù)類型的方法。因此,可以說單個參數(shù)的構(gòu)造函數(shù)提供了數(shù)據(jù)轉(zhuǎn)換的功能。下面通過一個例子進(jìn)一步說明單參數(shù)構(gòu)造函數(shù)的類型轉(zhuǎn)換功能。
#include
classA
{
public:
A(){ m=0; }
A(doublei) { m=i; }
voidprint() { cout<<M<
private:
doublem;
};
voidmain()
{
Aa(5);
a=10; //a與10是不同的數(shù)據(jù)類型
a.print();
}
程序的輸出結(jié)果為:
10
在該程序中,賦值語句a=10;中,賦值號兩邊數(shù)值10和對象a是兩上不相容的數(shù)據(jù)類型,可是它卻能順利通過編譯程序,并且輸出顯示正確結(jié)果,其主要原因是得益于單參數(shù)的構(gòu)造函數(shù)。編譯系統(tǒng)選通過標(biāo)準(zhǔn)數(shù)據(jù)類型轉(zhuǎn)換,將整型數(shù)值10轉(zhuǎn)換成double型,然后,再通過類中定義的單參數(shù)構(gòu)造函數(shù)將double型數(shù)值轉(zhuǎn)換為A類類型,最后把它賦值給a。這些轉(zhuǎn)換都是自動隱式完成的。
關(guān)于上面的程序,補充一點:
Aa = 10;
和
Aa;
a= 10;
兩者是不同的,前者對a進(jìn)行初使化,編譯器會嘗試將10隱式轉(zhuǎn)換為A類型,這樣將引起a的A(doublei)構(gòu)造函數(shù)直接被調(diào)用。
后者屬于賦值語句,編譯器將建立一個臨時對象,并將10隱式轉(zhuǎn)換為A類型。如果我們顯示調(diào)用
(A)10;
這也將建立一個臨時對象,引起A的構(gòu)造函數(shù)被調(diào)用。
還有一點要注意,編譯器只會進(jìn)行一次隱式轉(zhuǎn)換(C時刻庫的內(nèi)置類型如intshort char等)除外,下面的語句說明了這點:
m_rst->GetFields()->GetItem(nCol)->Value= (_bstr_t)sValue;
上面Value是COM的變體類型,“Value=”將引起operator= (_bstr_t)被調(diào)用。如果上面省略(_bstr_t),編譯器將發(fā)生錯誤,因為沒有operator= (char*)這樣的重載,編譯器不會為我們進(jìn)行兩次以上的隱式轉(zhuǎn)換。
在函數(shù)調(diào)用過程中,運算符重載和構(gòu)造也是一個函數(shù)調(diào)用,如果匹配的函數(shù)如無二義性,那么將可以產(chǎn)生一次隱式轉(zhuǎn)換。如果上句的Value變體類只有一個operate= (_bstr_t),那么既使這樣寫->Value= sValue; 編譯器也會試圖將sValue隱式轉(zhuǎn)換為_bstr_t類型。
還有一種情況
classA
{
inta;
public:
A(){ };
A(int_a) { a = _a; };
Operatorint() { return a; }
}
有如下調(diào)用:
Aa(10);
Aa2 = (int)(int)a; //只相當(dāng)于Aa2 = (int)a; 因為第一個就近已經(jīng)轉(zhuǎn)成了int,第二//個就不用再轉(zhuǎn)了
比較有意思吧,A類既有將int隱式轉(zhuǎn)換A的構(gòu)造,也有int()轉(zhuǎn)換函數(shù)供強制轉(zhuǎn)換,(int)(int)a將以就近原則的方式進(jìn)行。如果就近轉(zhuǎn)換失敗,編譯器將報錯。比如:
classB
{
};
Aa2 = (B)a;
或
Aa2 = (B)10;
編譯器報這樣的錯誤:"errorC2440: “類型轉(zhuǎn)換”:無法從“int”轉(zhuǎn)換為“B”"
可知,我們自己編寫的構(gòu)造和轉(zhuǎn)換函數(shù)多么重要。
轉(zhuǎn)換函數(shù)
轉(zhuǎn)換函數(shù)又稱類型強制轉(zhuǎn)換成員函數(shù),它是類中的一個非靜態(tài)成員函數(shù)。它的定義格式如下:
class<類型說明符1>
{
public:
operator<類型說明符2>();
…
}
這個轉(zhuǎn)換函數(shù)定義了由<類型說明符1>到<類型說明符2>之間的映射關(guān)系。可見,轉(zhuǎn)換函數(shù)是用來將一種類型的數(shù)據(jù)轉(zhuǎn)換成為另一種類型。下面通過一個例子說明轉(zhuǎn)換函數(shù)的功能。
#include
classRational
{
public:
Rational(intd, int n)
{
den= d;
num= n;
}
operatordouble();//類型轉(zhuǎn)換函數(shù)
private:
intden, num;
};
Rational::operatordouble()
{
returndouble(den)/double(num);
}
voidmain()
{
Rationalr(5, 8);
doubled = 4.7;
d+= r; //這句將調(diào)用隱式轉(zhuǎn)換,相當(dāng)于d= (double)r;
cout<<d<<ENDL;
}
程序輸出結(jié)果:
5.325
由程序可知,d是一個double型數(shù)值,r是Rational類的對象,這兩個不同類型的數(shù)據(jù)進(jìn)行加法之所以能夠進(jìn)行是得益于轉(zhuǎn)換函數(shù)operatordouble()。為使上述加法能夠進(jìn)行,編譯系統(tǒng)先檢查類Rational的說明,看是否存在在下轉(zhuǎn)換函數(shù)能夠?qū)ational類型的操作數(shù)轉(zhuǎn)換為double類型的操作數(shù)。由于Rational類中說明了轉(zhuǎn)換函數(shù)operatordouble(),它可以在程序運行時進(jìn)行上述類型轉(zhuǎn)換,因此,該程序中實現(xiàn)了d=r;的操作。
定義轉(zhuǎn)換函數(shù)時應(yīng)注意如下幾點:
(1)轉(zhuǎn)換函數(shù)是用戶定義的成員函數(shù),但它要是非靜態(tài)的。
(2)轉(zhuǎn)換函數(shù)的不可以有返回值。(意思是聲明中不可以有返回值)
(3)轉(zhuǎn)換函數(shù)也不帶任何參數(shù)。
(4)轉(zhuǎn)換函數(shù)函數(shù)還不能定義為友元函數(shù)。
轉(zhuǎn)換函數(shù)的名稱是類型轉(zhuǎn)換的目標(biāo)類型,因此,不必再為它指定返回值類型;轉(zhuǎn)換函數(shù)是被用于本類型的數(shù)值或變量轉(zhuǎn)換為其他的類型,也不必帶參數(shù)。
類中的構(gòu)造函數(shù)完成其他類型到類類型的轉(zhuǎn)換,而重載強制轉(zhuǎn)換完成類類型到其他類型的轉(zhuǎn)換。
上一篇:C++中Operator類型強制轉(zhuǎn)換成員函數(shù)解析
欄 目:C語言
本文標(biāo)題:c++類的隱式轉(zhuǎn)換與強制轉(zhuǎn)換重載詳解
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/4169.html
您可能感興趣的文章
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)式函數(shù)庫
- 04-02c語言中對數(shù)函數(shù)的表達(dá)式 c語言中對數(shù)怎么表達(dá)
- 04-02c語言沒有round函數(shù) round c語言
- 04-02C語言中怎么打出三角函數(shù) c語言中怎么打出三角函數(shù)的值
- 01-10c語言求1+2+...+n的解決方法
- 01-10求子數(shù)組最大和的解決方法詳解
- 01-10深入理解約瑟夫環(huán)的數(shù)學(xué)優(yōu)化方法
- 01-10深入二叉樹兩個結(jié)點的最低共同父結(jié)點的詳解
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設(shè)計- 解析最少換車次數(shù)的問題詳解
- 01-10c語言 跳臺階問題的解決方法


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達(dá)式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機閱讀
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 04-02jquery與jsp,用jquery
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-10C#中split用法實例總結(jié)
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-10delphi制作wav文件的方法
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改