第10章-C++程序設(shè)計(jì)(譚浩強(qiáng))電子課件_第1頁
第10章-C++程序設(shè)計(jì)(譚浩強(qiáng))電子課件_第2頁
第10章-C++程序設(shè)計(jì)(譚浩強(qiáng))電子課件_第3頁
第10章-C++程序設(shè)計(jì)(譚浩強(qiáng))電子課件_第4頁
第10章-C++程序設(shè)計(jì)(譚浩強(qiáng))電子課件_第5頁
已閱讀5頁,還剩73頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第10章運(yùn)算符重載10.1什么是運(yùn)算符重載10.2運(yùn)算符重載的方法10.3重載運(yùn)算符的規(guī)那么10.4運(yùn)算符重載函數(shù)作為類成員函數(shù)和友元函數(shù)10.5重載雙目運(yùn)算符10.6重載單目運(yùn)算符10.7重載流插入運(yùn)算符和流提取運(yùn)算符10.8不同類型數(shù)據(jù)間的轉(zhuǎn)換所謂重載,就是重新賦予新的含義。函數(shù)重載就是對(duì)一個(gè)已有的函數(shù)賦予新的含義,使之實(shí)現(xiàn)新功能。運(yùn)算符也可以重載。實(shí)際上,我們已經(jīng)在不知不覺之中使用了運(yùn)算符重載。現(xiàn)在要討論的問題是:用戶能否根據(jù)自己的需要對(duì)C++已提供的運(yùn)算符進(jìn)行重載,賦予它們新的含義,使之一名多用。譬如,能否用“+〞號(hào)進(jìn)行兩個(gè)復(fù)數(shù)的相加。在C++中不能在程序中直接用運(yùn)算符“+〞對(duì)復(fù)數(shù)進(jìn)行相加運(yùn)算。用戶必須自己設(shè)法實(shí)現(xiàn)復(fù)數(shù)相加。例如用戶可以通過定義一個(gè)專門的函數(shù)來實(shí)現(xiàn)復(fù)數(shù)相加。見例10.1。10.1什么是運(yùn)算符重載例10.1通過函數(shù)來實(shí)現(xiàn)復(fù)數(shù)相加。#include<iostream>usingnamespacestd;classComplex//定義Complex類{public:Complex(){real=0;imag=0;}//定義構(gòu)造函數(shù)Complex(doubler,doublei){real=r;imag=i;}//構(gòu)造函數(shù)重載Complexcomplex_add(Complex&c2);//聲明復(fù)數(shù)相加函數(shù)voiddisplay();//聲明輸出函數(shù)

private:doublereal;//實(shí)部doubleimag;//虛部};ComplexComplex∷complex_add(Complex&c2){Complexc;c.real=real+c2.real;c.imag=imag+c2.imag;returnc;}voidComplex∷display()//定義輸出函數(shù){cout<<″(″<<real<<″,″<<imag<<″i)″<<endl;}intmain(){Complexc1(3,4),c2(5,-10),c3;//定義3個(gè)復(fù)數(shù)對(duì)象c3=c1plex_add(c2);//調(diào)用復(fù)數(shù)相加函數(shù)cout<<″c1=″;c1.display();//輸出c1的值cout<<″c2=″;c2.display();//輸出c2的值cout<<″c1+c2=″;c3.display();//輸出c3的值return0;}運(yùn)行結(jié)果如下:c1=(3+4i)c2=(5-10i)c1+c2=(8,-6i)結(jié)果無疑是正確的,但調(diào)用方式不直觀、太煩瑣,使人感到很不方便。能否也和整數(shù)的加法運(yùn)算一樣,直接用加號(hào)“+〞來實(shí)現(xiàn)復(fù)數(shù)運(yùn)算呢?如c3=c1+c2;編譯系統(tǒng)就會(huì)自動(dòng)完成c1和c2兩個(gè)復(fù)數(shù)相加的運(yùn)算。如果能做到,就為對(duì)象的運(yùn)算提供了很大的方便。這就需要對(duì)運(yùn)算符“+〞進(jìn)行重載。運(yùn)算符重載的方法是定義一個(gè)重載運(yùn)算符的函數(shù),在需要執(zhí)行被重載的運(yùn)算符時(shí),系統(tǒng)就自動(dòng)調(diào)用該函數(shù),以實(shí)現(xiàn)相應(yīng)的運(yùn)算。也就是說,運(yùn)算符重載是通過定義函數(shù)實(shí)現(xiàn)的。運(yùn)算符重載實(shí)質(zhì)上是函數(shù)的重載。重載運(yùn)算符的函數(shù)一般格式如下:函數(shù)類型operator運(yùn)算符名稱(形參表列){對(duì)運(yùn)算符的重載處理}例如,想將“+〞用于Complex類(復(fù)數(shù))的加法運(yùn)算,函數(shù)的原型可以是這樣的:Complexoperator+(Complex&c1,Complex&c2);10.2運(yùn)算符重載的方法在定義了重載運(yùn)算符的函數(shù)后,可以說:函數(shù)operator+重載了運(yùn)算符+。為了說明在運(yùn)算符重載后,執(zhí)行表達(dá)式就是調(diào)用函數(shù)的過程,可以把兩個(gè)整數(shù)相加也想像為調(diào)用下面的函數(shù):intoperator+(inta,intb){return(a+b);}如果有表達(dá)式5+8,就調(diào)用此函數(shù),將5和8作為調(diào)用函數(shù)時(shí)的實(shí)參,函數(shù)的返回值為13。這就是用函數(shù)的方法理解運(yùn)算符。可以在例10.1程序的根底上重載運(yùn)算符“+〞,使之用于復(fù)數(shù)相加。例10.2改寫例10.1,重載運(yùn)算符“+〞,使之能用于兩個(gè)復(fù)數(shù)相加。#include<iostream>usingnamespacestd;classComplex{public:Complex(){real=0;imag=0;}Complex(doubler,doublei){real=r;imag=i;}Complexoperator+(Complex&c2);//聲明重載運(yùn)算符的函數(shù)voiddisplay();private:doublereal;doubleimag;};ComplexComplex∷operator+(Complex&c2)//定義重載運(yùn)算符的函數(shù){Complexc;c.real=real+c2.real;c.imag=imag+c2.imag;returnc;}voidComplex∷display(){cout<<″(″<<real<<″,″<<imag<<″i)″<<endl;}intmain(){Complexc1(3,4),c2(5,-10),c3;c3=c1+c2;//運(yùn)算符+用于復(fù)數(shù)運(yùn)算cout<<″c1=″;c1.display();cout<<″c2=″;c2.display();cout<<″c1+c2=″;c3.display();return0;}運(yùn)行結(jié)果與例10.1相同:c1=(3+4i)c2=(5-10i)c1+c2=(8,-6i)請(qǐng)比較例10.1和例10.2,只有兩處不同:(1)在例10.2中以operator+函數(shù)取代了例10.1中的complex_add函數(shù),而且只是函數(shù)名不同,函數(shù)體和函數(shù)返回值的類型都是相同的。(2)在main函數(shù)中,以“c3=c1+c2;〞取代了例10.1中的“c3=c1plex_add(c2);〞。在將運(yùn)算符+重載為類的成員函數(shù)后,C++編譯系統(tǒng)將程序中的表達(dá)式c1+c2解釋為c1.operator+(c2)//其中c1和c2是Complex類的對(duì)象即以c2為實(shí)參調(diào)用c1的運(yùn)算符重載函數(shù)operator+(Complex&c2),進(jìn)行求值,得到兩個(gè)復(fù)數(shù)之和。雖然重載運(yùn)算符所實(shí)現(xiàn)的功能完全可以用函數(shù)實(shí)現(xiàn),但是使用運(yùn)算符重載能使用戶程序易于編寫、閱讀和維護(hù)。在實(shí)際工作中,類的聲明和類的使用往往是別離的。假設(shè)在聲明Complex類時(shí),對(duì)運(yùn)算符+,-,*,/都進(jìn)行了重載,那么使用這個(gè)類的用戶在編程時(shí)可以完全不考慮函數(shù)是怎么實(shí)現(xiàn)的,放心大膽地直接使用+,-,*,/進(jìn)行復(fù)數(shù)的運(yùn)算即可,十分方便。對(duì)上面的運(yùn)算符重載函數(shù)operator+還可以改寫得更簡(jiǎn)練一些:ComplexComplex∷operator+(Complex&c2){returnComplex(real+c2.real,imag+c2.imag);}需要說明的是:運(yùn)算符被重載后,其原有的功能仍然保存,沒有喪失或改變。通過運(yùn)算符重載,擴(kuò)大了C++已有運(yùn)算符的作用范圍,使之能用于類對(duì)象。運(yùn)算符重載對(duì)C++有重要的意義,把運(yùn)算符重載和類結(jié)合起來,可以在C++程序中定義出很有實(shí)用意義而使用方便的新的數(shù)據(jù)類型。運(yùn)算符重載使C++具有更強(qiáng)大的功能、更好的可擴(kuò)充性和適應(yīng)性,這是C++最吸引人的特點(diǎn)之一。(1)C++不允許用戶自己定義新的運(yùn)算符,只能對(duì)已有的C++運(yùn)算符進(jìn)行重載?!?〕C++允許重載的運(yùn)算符C++中絕大局部的運(yùn)算符允許重載。具體規(guī)定見書中表10.1。不能重載的運(yùn)算符只有5個(gè):.(成員訪問運(yùn)算符).*(成員指針訪問運(yùn)算符)∷(域運(yùn)算符)sizeof(長(zhǎng)度運(yùn)算符)?:(條件運(yùn)算符)10.3重載運(yùn)算符的規(guī)那么前兩個(gè)運(yùn)算符不能重載是為了保證訪問成員的功能不能被改變,域運(yùn)算符和sizeof運(yùn)算符的運(yùn)算對(duì)象是類型而不是變量或一般表達(dá)式,不具重載的特征。(3)重載不能改變運(yùn)算符運(yùn)算對(duì)象(即操作數(shù))的個(gè)數(shù)。(4)重載不能改變運(yùn)算符的優(yōu)先級(jí)別。(5)重載不能改變運(yùn)算符的結(jié)合性。(6)重載運(yùn)算符的函數(shù)不能有默認(rèn)的參數(shù),否那么就改變了運(yùn)算符參數(shù)的個(gè)數(shù),與前面第(3)點(diǎn)矛盾。(7)重載的運(yùn)算符必須和用戶定義的自定義類型的對(duì)象一起使用,其參數(shù)至少應(yīng)有一個(gè)是類對(duì)象(或類對(duì)象的引用)。也就是說,參數(shù)不能全部是C++的標(biāo)準(zhǔn)類型,以防止用戶修改用于標(biāo)準(zhǔn)類型數(shù)據(jù)的運(yùn)算符的性質(zhì)。(8)用于類對(duì)象的運(yùn)算符一般必須重載,但有兩個(gè)例外,運(yùn)算符“=〞和“&〞不必用戶重載。①賦值運(yùn)算符(=)可以用于每一個(gè)類對(duì)象,可以利用它在同類對(duì)象之間相互賦值。②地址運(yùn)算符&也不必重載,它能返回類對(duì)象在內(nèi)存中的起始地址。(9)應(yīng)當(dāng)使重載運(yùn)算符的功能類似于該運(yùn)算符作用于標(biāo)準(zhǔn)類型數(shù)據(jù)時(shí)所實(shí)現(xiàn)的功能。(10)運(yùn)算符重載函數(shù)可以是類的成員函數(shù)(如例10.2),也可以是類的友元函數(shù),還可以是既非類的成員函數(shù)也不是友元函數(shù)的普通函數(shù)。在本章例10.2程序中對(duì)運(yùn)算符“+〞進(jìn)行了重載,使之能用于兩個(gè)復(fù)數(shù)的相加。在該例中運(yùn)算符重載函數(shù)operator+作為Complex類中的成員函數(shù)。“+〞是雙目運(yùn)算符,為什么在例10.2程序中的重載函數(shù)中只有一個(gè)參數(shù)呢?實(shí)際上,運(yùn)算符重載函數(shù)有兩個(gè)參數(shù),由于重載函數(shù)是Complex類中的成員函數(shù),有一個(gè)參數(shù)是隱含的,運(yùn)算符函數(shù)是用this指針隱式地訪問類對(duì)象的成員。10.4運(yùn)算符重載函數(shù)作為類成員函數(shù)和友元函數(shù)可以看到,重載函數(shù)operator+訪問了兩個(gè)對(duì)象中的成員,一個(gè)是this指針指向的對(duì)象中的成員,一個(gè)是形參對(duì)象中的成員。如this->real+c2.real,this->real就是c1.real。在10.2節(jié)中已說明,在將運(yùn)算符函數(shù)重載為成員函數(shù)后,如果出現(xiàn)含該運(yùn)算符的表達(dá)式,如c1+c2,編譯系統(tǒng)把它解釋為c1.operator+(c2)即通過對(duì)象c1調(diào)用運(yùn)算符重載函數(shù),并以表達(dá)式中第二個(gè)參數(shù)(運(yùn)算符右側(cè)的類對(duì)象c2)作為函數(shù)實(shí)參。運(yùn)算符重載函數(shù)的返回值是Complex類型,返回值是復(fù)數(shù)c1和c2之和(Complex(c1.real+c2.real,c1.imag+c2.imag))。運(yùn)算符重載函數(shù)除了可以作為類的成員函數(shù)外,還可以是非成員函數(shù)。可以將例10.2改寫為例10.3。例10.3將運(yùn)算符“+〞重載為適用于復(fù)數(shù)加法,重載函數(shù)不作為成員函數(shù),而放在類外,作為Complex類的友元函數(shù)。#include<iostream>usingnamespacestd;classComplex{public:Complex(){real=0;imag=0;}Complex(doubler,doublei){real=r;imag=i;}friendComplexoperator+(Complex&c1,Complex&c2);//重載函數(shù)作為友元函數(shù)voiddisplay();private:doublereal;doubleimag;};Complexoperator+(Complex&c1,Complex&c2)//定義作為友元函數(shù)的重載函數(shù){returnComplex(c1.real+c2.real,c1.imag+c2.imag);}voidComplex∷display(){cout<<″(″<<real<<″,″<<imag<<″i)″<<endl;}intmain(){Complexc1(3,4),c2(5,-10),c3;c3=c1+c2;cout<<″c1=″;c1.display();cout<<″c2=″;c2.display();cout<<″c1+c2=″;c3.display();}與例10.2相比較,只作了一處改動(dòng),將運(yùn)算符函數(shù)不作為成員函數(shù),而把它放在類外,在Complex類中聲明它為友元函數(shù)。同時(shí)將運(yùn)算符函數(shù)改為有兩個(gè)參數(shù)。在將運(yùn)算符“+〞重載為非成員函數(shù)后,C++編譯系統(tǒng)將程序中的表達(dá)式c1+c2解釋為operator+(c1,c2)即執(zhí)行c1+c2相當(dāng)于調(diào)用以下函數(shù):Complexoperator+(Complex&c1,Complex&c2){returnComplex(c1.real+c2.real,c1.imag+c2.imag);}求出兩個(gè)復(fù)數(shù)之和。運(yùn)行結(jié)果同例10.2。為什么把運(yùn)算符函數(shù)作為友元函數(shù)呢?因?yàn)檫\(yùn)算符函數(shù)要訪問Complex類對(duì)象中的成員。如果運(yùn)算符函數(shù)不是Complex類的友元函數(shù),而是一個(gè)普通的函數(shù),它是沒有權(quán)利訪問Complex類的私有成員的。在10.2節(jié)中曾提到過:運(yùn)算符重載函數(shù)可以是類的成員函數(shù),也可以是類的友元函數(shù),還可以是既非類的成員函數(shù)也不是友元函數(shù)的普通函數(shù)?,F(xiàn)在分別討論這3種情況。首先,只有在極少的情況下才使用既不是類的成員函數(shù)也不是友元函數(shù)的普通函數(shù),原因是上面提到的,普通函數(shù)不能直接訪問類的私有成員。在剩下的兩種方式中,什么時(shí)候應(yīng)該用成員函數(shù)方式,什么時(shí)候應(yīng)該用友元函數(shù)方式?二者有何區(qū)別呢?如果將運(yùn)算符重載函數(shù)作為成員函數(shù),它可以通過this指針自由地訪問本類的數(shù)據(jù)成員,因此可以少寫一個(gè)函數(shù)的參數(shù)。但必須要求運(yùn)算表達(dá)式第一個(gè)參數(shù)(即運(yùn)算符左側(cè)的操作數(shù))是一個(gè)類對(duì)象,而且與運(yùn)算符函數(shù)的類型相同。因?yàn)楸仨毻ㄟ^類的對(duì)象去調(diào)用該類的成員函數(shù),而且只有運(yùn)算符重載函數(shù)返回值與該對(duì)象同類型,運(yùn)算結(jié)果才有意義。在例10.2中,表達(dá)式c1+c2中第一個(gè)參數(shù)c1是Complex類對(duì)象,運(yùn)算符函數(shù)返回值的類型也是Complex,這是正確的。如果c1不是Complex類,它就無法通過隱式this指針訪問Complex類的成員了。如果函數(shù)返回值不是Complex類復(fù)數(shù),顯然這種運(yùn)算是沒有實(shí)際意義的。如想將一個(gè)復(fù)數(shù)和一個(gè)整數(shù)相加,如c1+i,可以將運(yùn)算符重載函數(shù)作為成員函數(shù),如下面的形式:ComplexComplex∷operator+(int&i)//運(yùn)算符重載函數(shù)作為Complex類的成員函數(shù){returnComplex(real+i,imag);}注意在表達(dá)式中重載的運(yùn)算符“+〞左側(cè)應(yīng)為Complex類的對(duì)象,如c3=c2+i;不能寫成c3=i+c2;//運(yùn)算符“+〞的左側(cè)不是類對(duì)象,編譯出錯(cuò)如果出于某種考慮,要求在使用重載運(yùn)算符時(shí)運(yùn)算符左側(cè)的操作數(shù)是整型量〔如表達(dá)式i+c2,運(yùn)算符左側(cè)的操作數(shù)i是整數(shù)〕,這時(shí)是無法利用前面定義的重載運(yùn)算符的,因?yàn)闊o法調(diào)用i.operator+函數(shù)。可想而知,如果運(yùn)算符左側(cè)的操作數(shù)屬于C++標(biāo)準(zhǔn)類型(如int)或是一個(gè)其他類的對(duì)象,那么運(yùn)算符重載函數(shù)不能作為成員函數(shù),只能作為非成員函數(shù)。如果函數(shù)需要訪問類的私有成員,那么必須聲明為友元函數(shù)??梢栽贑omplex類中聲明:friendComplexoperator+(int&i,Complex&c);//第一個(gè)參數(shù)可以不是類對(duì)象在類外定義友元函數(shù):Complexoperator+(int&i,Complex&c)//運(yùn)算符重載函數(shù)不是成員函數(shù){returnComplex(i+c.real,c.imag);}將雙目運(yùn)算符重載為友元函數(shù)時(shí),在函數(shù)的形參表列中必須有兩個(gè)參數(shù),不能省略,形參的順序任意,不要求第一個(gè)參數(shù)必須為類對(duì)象。但在使用運(yùn)算符的表達(dá)式中,要求運(yùn)算符左側(cè)的操作數(shù)與函數(shù)第一個(gè)參數(shù)對(duì)應(yīng),運(yùn)算符右側(cè)的操作數(shù)與函數(shù)的第二個(gè)參數(shù)對(duì)應(yīng)。如c3=i+c2;//正確,類型匹配c3=c2+i;//錯(cuò)誤,類型不匹配請(qǐng)注意,數(shù)學(xué)上的交換律在此不適用。如果希望適用交換律,那么應(yīng)再重載一次運(yùn)算符“+〞。如Complexoperator+(Complex&c,int&i)//此時(shí)第一個(gè)參數(shù)為類對(duì)象{returnComplex(i+c.real,c.imag);}這樣,使用表達(dá)式i+c2和c2+i都合法,編譯系統(tǒng)會(huì)根據(jù)表達(dá)式的形式選擇調(diào)用與之匹配的運(yùn)算符重載函數(shù)??梢詫⒁陨蟽蓚€(gè)運(yùn)算符重載函數(shù)都作為友元函數(shù),也可以將一個(gè)運(yùn)算符重載函數(shù)(運(yùn)算符左側(cè)為對(duì)象名的)作為成員函數(shù),另一個(gè)(運(yùn)算符左側(cè)不是對(duì)象名的)作為友元函數(shù)。但不可能將兩個(gè)都作為成員函數(shù),原因是顯然的。C++規(guī)定,有的運(yùn)算符(如賦值運(yùn)算符、下標(biāo)運(yùn)算符、函數(shù)調(diào)用運(yùn)算符)必須定義為類的成員函數(shù),有的運(yùn)算符那么不能定義為類的成員函數(shù)(如流插入“<<〞和流提取運(yùn)算符“>>〞、類型轉(zhuǎn)換運(yùn)算符)。由于友元的使用會(huì)破壞類的封裝,因此從原那么上說,要盡量將運(yùn)算符函數(shù)作為成員函數(shù)。但考慮到各方面的因素,一般將單目運(yùn)算符重載為成員函數(shù),將雙目運(yùn)算符重載為友元函數(shù)。在學(xué)習(xí)了本章第10.7節(jié)例10.9的討論后,讀者對(duì)此會(huì)有更深入的認(rèn)識(shí)。說明:有的C++編譯系統(tǒng)(如VisualC++6.0)沒有完全實(shí)現(xiàn)C++標(biāo)準(zhǔn),它所提供不帶后綴.h的頭文件不支持把成員函數(shù)重載為友元函數(shù)。上面例10.3程序在GCC中能正常運(yùn)行,而在VisualC++6.0中會(huì)編譯出錯(cuò)。但是VisualC++所提供的老形式的帶后綴.h的頭文件可以支持此項(xiàng)功能,因此可以將程序頭兩行修改如下,即可順利運(yùn)行:#include<iostream.h>以后如遇到類似情況,亦可照此辦理。雙目運(yùn)算符(或稱二元運(yùn)算符)是C++中最常用的運(yùn)算符。雙目運(yùn)算符有兩個(gè)操作數(shù),通常在運(yùn)算符的左右兩側(cè),如3+5,a=b,i<10等。在重載雙目運(yùn)算符時(shí),不言而喻在函數(shù)中應(yīng)該有兩個(gè)參數(shù)。下面再舉一個(gè)例子說明重載雙目運(yùn)算符的應(yīng)用。10.5重載雙目運(yùn)算符例10.4定義一個(gè)字符串類String,用來存放不定長(zhǎng)的字符串,重載運(yùn)算符“==〞,“<〞和“>〞,用于兩個(gè)字符串的等于、小于和大于的比較運(yùn)算。為了使讀者便于理解程序,同時(shí)也使讀者了解建立程序的步驟,下面分幾步來介紹編程過程。(1)先建立一個(gè)String類:#include<iostream>usingnamespacestd;classString{public:String(){p=NULL;}//默認(rèn)構(gòu)造函數(shù)String(char*str);//構(gòu)造函數(shù)voiddisplay();private:char*p;//字符型指針,用于指向字符串};String∷String(char*str)//定義構(gòu)造函數(shù){p=str;}//使p指向?qū)崊⒆址畍oidString∷display()//輸出p所指向的字符串{cout<<p;}intmain(){Stringstring1(″Hello″),string2(″Book″);string1.display();cout<<endl;string2.display();return0;}運(yùn)行結(jié)果為HelloBook(2)有了這個(gè)根底后,再增加其他必要的內(nèi)容。現(xiàn)在增加對(duì)運(yùn)算符重載的局部。為便于編寫和調(diào)試,先重載一個(gè)運(yùn)算符“>〞。程序如下:#include<iostream>#include<string>usingnamespacestd;classString{public:String(){p=NULL;}String(char*str);friendbooloperator>(String&string1,String&string2);//聲明運(yùn)算符函數(shù)為友元函數(shù)voiddisplay();private:char*p;//字符型指針,用于指向字符串};String∷String(char*str){p=str;}voidString∷display()//輸出p所指向的字符串{cout<<p;}booloperator>(String&string1,String&string2)//定義運(yùn)算符重載函數(shù){if(strcmp(string1.p,string2.p)>0)returntrue;elsereturnfalse;}intmain(){Stringstring1(″Hello″),string2(″Book″);cout<<(string1>string2)<<endl;}程序運(yùn)行結(jié)果為1。這只是一個(gè)并不很完善的程序,但是,已經(jīng)完成了實(shí)質(zhì)性的工作了,運(yùn)算符重載成功了。其他兩個(gè)運(yùn)算符的重載如法炮制即可。(3)擴(kuò)展到對(duì)3個(gè)運(yùn)算符重載。在String類體中聲明3個(gè)成員函數(shù):friendbooloperator>(String&string1,String&string2);friendbooloperator<(String&string1,String&string2);friendbooloperator==(String&string1,String&string2);在類外分別定義3個(gè)運(yùn)算符重載函數(shù):booloperator>(String&string1,String&string2)//對(duì)運(yùn)算符“>〞重載{if(strcmp(string1.p,string2.p)>0)returntrue;elsereturnfalse;}booloperator<(String&string1,String&string2)//對(duì)運(yùn)算符“<〞重載{if(strcmp(string1.p,string2.p)<0)returntrue;elsereturnfalse;}booloperator==(String&string1,String&string2)//對(duì)運(yùn)算符“==〞重載{if(strcmp(string1.p,string2.p)==0)returntrue;elsereturnfalse;}再修改主函數(shù):intmain(){Stringstring1(″Hello″),string2(″Book″),string3(″Computer″);cout<<(string1>string2)<<endl;//比較結(jié)果應(yīng)該為truecout<<(string1<string3)<<endl;//比較結(jié)果應(yīng)該為falsecout<<(string1==string2)<<endl;//比較結(jié)果應(yīng)該為falsereturn0;}運(yùn)行結(jié)果為100結(jié)果顯然是對(duì)的。到此為止,主要任務(wù)根本完成。(4)再進(jìn)一步修飾完善,使輸出結(jié)果更直觀。下面給出最后的程序。#include<iostream>usingnamespacestd;classString{public:String(){p=NULL;}String(char*str);friendbooloperator>(String&string1,String&string2);friendbooloperator<(String&string1,String&string2);friendbooloperator==(String&string1,String&string2);voiddisplay();private:char*p;};String∷String(char*str){p=str;}voidString∷display()//輸出p所指向的字符串{cout<<p;}booloperator>(String&string1,String&string2){if(strcmp(string1.p,string2.p)>0)returntrue;elsereturnfalse;}booloperator<(String&string1,String&string2){if(strcmp(string1.p,string2.p)<0)returntrue;elsereturnfalse;}booloperator==(String&string1,String&string2){if(strcmp(string1.p,string2.p)==0)returntrue;elsereturnfalse;}voidcompare(String&string1,String&string2){if(operator>(string1,string2)==1){string1.display();cout<<″>″;string2.display();}elseif(operator<(string1,string2)==1){string1.display();cout<<″<″;string2.display();}elseif(operator==(string1,string2)==1){string1.display();cout<<″=″;string2.display();}cout<<endl;}intmain(){Stringstring1(″Hello″),string2(″Book″),string3(″Computer″),string4(″Hello″);compare(string1,string2);compare(string2,string3);compare(string1,string4);return0;}運(yùn)行結(jié)果為Hello>BookBook<ComputerHello==Hello增加了一個(gè)compare函數(shù),用來對(duì)兩個(gè)字符串進(jìn)行比較,并輸出相應(yīng)的信息。這樣可以減輕主函數(shù)的負(fù)擔(dān),使主函數(shù)簡(jiǎn)明易讀。通過這個(gè)例子,不僅可以學(xué)習(xí)到有關(guān)雙目運(yùn)算符重載的知識(shí),而且還可以學(xué)習(xí)怎樣去編寫C++程序。這種方法的指導(dǎo)思想是:先搭框架,逐步擴(kuò)充,由簡(jiǎn)到繁,最后完善。邊編程,邊調(diào)試,邊擴(kuò)充。千萬不要企圖在一開始時(shí)就解決所有的細(xì)節(jié)。類是可擴(kuò)充的,可以一步一步地?cái)U(kuò)充它的功能。最好直接在計(jì)算機(jī)上寫程序,每一步都要上機(jī)調(diào)試,調(diào)試通過了前面一步再做下一步,步步為營(yíng)。這樣編程和調(diào)試的效率是比較高的。讀者可以試驗(yàn)一下。單目運(yùn)算符只有一個(gè)操作數(shù),如!a,-b,&c,*p,還有最常用的++i和--i等。重載單目運(yùn)算符的方法與重載雙目運(yùn)算符的方法是類似的。但由于單目運(yùn)算符只有一個(gè)操作數(shù),因此運(yùn)算符重載函數(shù)只有一個(gè)參數(shù),如果運(yùn)算符重載函數(shù)作為成員函數(shù),那么還可省略此參數(shù)。下面以自增運(yùn)算符“++〞為例,介紹單目運(yùn)算符的重載。10.6重載單目運(yùn)算符例10.5有一個(gè)Time類,包含數(shù)據(jù)成員minute(分)和sec(秒),模擬秒表,每次走一秒,滿60秒進(jìn)一分鐘,此時(shí)秒又從0開始算。要求輸出分和秒的值。#include<iostream>usingnamespacestd;classTime{public:Time(){minute=0;sec=0;}//默認(rèn)構(gòu)造函數(shù)Time(intm,ints):minute(m),sec(s){}//構(gòu)造函數(shù)重載Timeoperator++();//聲明運(yùn)算符重載函數(shù)voiddisplay(){cout<<minute<<″:″<<sec<<endl;}//定義輸出時(shí)間函數(shù)private:intminute;intsec;};TimeTime∷operator++()//定義運(yùn)算符重載函數(shù){if(++sec>=60){sec-=60;//滿60秒進(jìn)1分鐘++minute;}return*this;//返回當(dāng)前對(duì)象值}intmain(){Timetime1(34,0);for(inti=0;i<61;i++){++time1;time1.display();}return0;}運(yùn)行情況如下:34:134:2┆34:5935:035:1(共輸出61行)可以看到:在程序中對(duì)運(yùn)算符“++〞進(jìn)行了重載,使它能用于Time類對(duì)象?!?+〞和“--〞運(yùn)算符有兩種使用方式,前置自增運(yùn)算符和后置自增運(yùn)算符,它們的作用是不一樣的,在重載時(shí)怎樣區(qū)別這二者呢?針對(duì)“++〞和“--〞這一特點(diǎn),C++約定:在自增(自減)運(yùn)算符重載函數(shù)中,增加一個(gè)int型形參,就是后置自增(自減)運(yùn)算符函數(shù)。例10.6在例10.5程序的根底上增加對(duì)后置自增運(yùn)算符的重載。修改后的程序如下:#include<iostream>usingnamespacestd;classTime{public:Time(){minute=0;sec=0;}Time(intm,ints):minute(m),sec(s){}Timeoperator++();//聲明前置自增運(yùn)算符“++〞重載函數(shù)Timeoperator++(int);//聲明后置自增運(yùn)算符“++〞重載函數(shù)voiddisplay(){cout<<minute<<″:″<<sec<<endl;}private:intminute;intsec;};TimeTime∷operator++()//定義前置自增運(yùn)算符“++〞重載函數(shù){if(++sec>=60){sec-=60;++minute;}return*this;//返回自加后的當(dāng)前對(duì)象}TimeTime∷operator++(int)//定義后置自增運(yùn)算符“++〞重載函數(shù){Timetemp(*this);sec++;if(sec>=60){sec-=60;++minute;}returntemp;//返回的是自加前的對(duì)象}intmain(){Timetime1(34,59),time2;cout<<″time1:″;time1.display();++time1;cout<<″++time1:″;time1.display();time2=time1++;//將自加前的對(duì)象的值賦給time2cout<<″time1++:″;time1.display();cout<<″time2:″;time2.display();//輸出time2對(duì)象的值}請(qǐng)注意前置自增運(yùn)算符“++〞和后置自增運(yùn)算符“++〞二者作用的區(qū)別。前者是先自加,返回的是修改后的對(duì)象本身。后者返回的是自加前的對(duì)象,然后對(duì)象自加。請(qǐng)仔細(xì)分析后置自增運(yùn)算符重載函數(shù)。運(yùn)行結(jié)果如下:time1:34:59(time1原值)++time1:35:0(執(zhí)行++time1后time1的值)time1++:35:1(再執(zhí)行time1++后time1的值)time2:35:0(time2保存的是執(zhí)行time1++前time1的值)可以看到:重載后置自增運(yùn)算符時(shí),多了一個(gè)int型的參數(shù),增加這個(gè)參數(shù)只是為了與前置自增運(yùn)算符重載函數(shù)有所區(qū)別,此外沒有任何作用。編譯系統(tǒng)在遇到重載后置自增運(yùn)算符時(shí),會(huì)自動(dòng)調(diào)用此函數(shù)。C++的流插入運(yùn)算符“<<〞和流提取運(yùn)算符“>>〞是C++在類庫(kù)中提供的,所有C++編譯系統(tǒng)都在類庫(kù)中提供輸入流類istream和輸出流類ostream。cin和cout分別是istream類和ostream類的對(duì)象。在類庫(kù)提供的頭文件中已經(jīng)對(duì)“<<〞和“>>〞進(jìn)行了重載,使之作為流插入運(yùn)算符和流提取運(yùn)算符,能用來輸出和輸入C++標(biāo)準(zhǔn)類型的數(shù)據(jù)。因此,在本書前面幾章中,但凡用“cout<<〞和“cin>>〞對(duì)標(biāo)準(zhǔn)類型數(shù)據(jù)進(jìn)行輸入輸出的,都要用#include<iostream>把頭文件包含到本程序文件中。10.7重載流插入運(yùn)算符和流提取運(yùn)算符用戶自己定義的類型的數(shù)據(jù),是不能直接用“<<〞和“>>〞來輸出和輸入的。如果想用它們輸出和輸入自己聲明的類型的數(shù)據(jù),必須對(duì)它們重載。對(duì)“<<〞和“>>〞重載的函數(shù)形式如下:istream&operator>>(istream&,自定義類&);ostream&operator<<(ostream&,自定義類&);即重載運(yùn)算符“>>〞的函數(shù)的第一個(gè)參數(shù)和函數(shù)的類型都必須是istream&類型,第二個(gè)參數(shù)是要進(jìn)行輸入操作的類。重載“<<〞的函數(shù)的第一個(gè)參數(shù)和函數(shù)的類型都必須是ostream&類型,第二個(gè)參數(shù)是要進(jìn)行輸出操作的類。因此,只能將重載“>>〞和“<<〞的函數(shù)作為友元函數(shù)或普通的函數(shù),而不能將它們定義為成員函數(shù)。在程序中,人們希望能用插入運(yùn)算符“<<〞來輸出用戶自己聲明的類的對(duì)象的信息,這就需要重載流插入運(yùn)算符“<<〞。例10.7在例10.2的根底上,用重載的“<<〞輸出復(fù)數(shù)。#include<iostream>usingnamespacestd;classComplex{public:Complex(){real=0;imag=0;}Complex(doubler,doublei){real=r;imag=i;}Complexoperator+(Complex&c2);//運(yùn)算符“+〞重載為成員函數(shù)friendostream&operator<<(ostream&,Complex&);//運(yùn)算符“<<〞重載為友元函數(shù)private:10.7.1重載流插入運(yùn)算符“<<〞doublereal;doubleimag;};ComplexComplex∷operator+(Complex&c2)//定義運(yùn)算符“+〞重載函數(shù){returnComplex(real+c2.real,imag+c2.imag);}ostream&operator<<(ostream&output,Complex&c)//定義運(yùn)算符“<<〞重載函數(shù){output<<″(″<<c.real<<″+″<<c.imag<<″i)″<<endl;returnoutput;}intmain(){Complexc1(2,4),c2(6,10),c3;c3=c1+c2;cout<<c3;return0;}(在VisualC++6.0環(huán)境下運(yùn)行時(shí),需將第一行改為#include<iostream.h>,并刪去第2行。)運(yùn)行結(jié)果為(8+14i)可以看到在對(duì)運(yùn)算符“<<〞重載后,在程序中用“<<〞不僅能輸出標(biāo)準(zhǔn)類型數(shù)據(jù),而且可以輸出用戶自己定義的類對(duì)象。用“cout<<c3〞即能以復(fù)數(shù)形式輸出復(fù)數(shù)對(duì)象c3的值。形式直觀,可讀性好,易于使用。下面對(duì)怎樣實(shí)現(xiàn)運(yùn)算符重載作一些說明。程序中重載了運(yùn)算符“<<〞,運(yùn)算符重載函數(shù)中的形參output是ostream類對(duì)象的引用,形參名output是用戶任意起的。分析main函數(shù)最后第二行:cout<<c3;運(yùn)算符“<<〞的左面是cout,前面已提到cout是ostream類對(duì)象?!?lt;<〞的右面是c3,它是Complex類對(duì)象。由于已將運(yùn)算符“<<〞的重載函數(shù)聲明為Complex類的友元函數(shù),編譯系統(tǒng)把“cout<<c3〞解釋為operator<<(cout,c3)即以cout和c3作為實(shí)參,調(diào)用下面的operator<<函數(shù):ostream&operator<<(ostream&output,Complex&c){output<<″(″<<c.real<<″+″<<c.imag<<″i)″<<endl;returnoutput;}調(diào)用函數(shù)時(shí),形參output成為cout的引用,形參c成為c3的引用。因此調(diào)用函數(shù)的過程相當(dāng)于執(zhí)行:cout<<″(″<<c3.real<<″+″<<c3.imag<<″i)″<<endl;returncout;請(qǐng)注意:上一行中的“<<〞是C++預(yù)定義的流插入符,因?yàn)樗覀?cè)的操作數(shù)是字符串常量和double類型數(shù)據(jù)。執(zhí)行cout語句輸出復(fù)數(shù)形式的信息。然后執(zhí)行return語句。請(qǐng)思考:returnoutput的作用是什么?答復(fù)是能連續(xù)向輸出流插入信息。output是ostream類的對(duì)象,它是實(shí)參cout的引用,也就是cout通過傳送地址給output,使它們二者共享同一段存儲(chǔ)單元,或者說output是cout的別名。因此,returnoutput就是returncout,將輸出流cout的現(xiàn)狀返回,即保存輸出流的現(xiàn)狀。請(qǐng)問返回到哪里?剛剛是在執(zhí)行cout<<c3;在cout<<c3的返回值是cout的當(dāng)前值。如果有以下輸出:cout<<c3<<c2;先處理cout<<c3,即(cout<<c3)<<c2;而執(zhí)行(cout<<c3)得到的結(jié)果就是具有新內(nèi)容的流對(duì)象cout,因此,(cout<<c3)<<c2相當(dāng)于cout(新值)<<c2。運(yùn)算符“<<〞左側(cè)是ostream類對(duì)象cout,右側(cè)是Complex類對(duì)象c2,那么再次調(diào)用運(yùn)算符“<<〞重載函數(shù),接著向輸出流插入c2的數(shù)據(jù)?,F(xiàn)在可以理解了為什么C++規(guī)定運(yùn)算符“<<〞重載函數(shù)的第一個(gè)參數(shù)和函數(shù)的類型都必須是ostream類型的引用,就是為了返回cout的當(dāng)前值以便連續(xù)輸出。請(qǐng)讀者注意區(qū)分什么情況下的“<<〞是標(biāo)準(zhǔn)類型數(shù)據(jù)的流插入符,什么情況下的“<<〞是重載的流插入符。如cout<<c3<<5<<endl;有下劃線的是調(diào)用重載的流插入符,后面兩個(gè)“<<〞不是重載的流插入符,因?yàn)樗挠覀?cè)不是Complex類對(duì)象而是標(biāo)準(zhǔn)類型的數(shù)據(jù),是用預(yù)定義的流插入符處理的。還有一點(diǎn)要說明:在本程序中,在Complex類中定義了運(yùn)算符“<<〞重載函數(shù)為友元函數(shù),因此只有在輸出Complex類對(duì)象時(shí)才能使用重載的運(yùn)算符,對(duì)其他類型的對(duì)象是無效的。如cout<<time1;//time1是Time類對(duì)象,不能使用用于Complex類的重載運(yùn)算符C++預(yù)定義的運(yùn)算符“>>〞的作用是從一個(gè)輸入流中提取數(shù)據(jù),如“cin>>i;〞表示從輸入流中提取一個(gè)整數(shù)賦給變量i(假設(shè)已定義i為int型)。重載流提取運(yùn)算符的目的是希望將“>>〞用于輸入自定義類型的對(duì)象的信息。10.7.2重載流提取運(yùn)算符“>>〞例10.8在例10.7的根底上,增加重載流提取運(yùn)算符“>>〞,用“cin>>〞輸入復(fù)數(shù),用“cout<<〞輸出復(fù)數(shù)。#include<iostream>usingnamespacestd;classComplex{public:friendostream&operator<<(ostream&,Complex&);//聲明重載運(yùn)算符“<<〞friendistream&operator>>(istream&,Complex&);//聲明重載運(yùn)算符“>>〞private:doublereal;doubleimag;};ostream&operator<<(ostream&output,Complex&c)//定義重載運(yùn)算符“<<〞{output<<″(″<<c.real<<″+″<<c.imag<<″i)″;returnoutput;}istream&operator>>(istream&input,Complex&c)//定義重載運(yùn)算符“>>〞{cout<<″inputrealpartandimaginarypartofcomplexnumber:″;input>>c.real>>c.imag;returninput;}intmain(){Complexc1,c2;cin>>c1>>c2;cout<<″c1=″<<c1<<endl;cout<<″c2=″<<c2<<endl;return0;}運(yùn)行情況如下:inputrealpartandimaginarypartofcomplexnumber:36↙inputrealpartandimaginarypartofcomplexnumber:410↙c1=(3+6i)c2=(4+10i)以上運(yùn)行結(jié)果無疑是正確的,但并不完善。在輸入復(fù)數(shù)的虛部為正值時(shí),輸出的結(jié)果是沒有問題的,但是虛部如果是負(fù)數(shù),就不理想,請(qǐng)觀察輸出結(jié)果。inputrealpartandimaginarypartofcomplexnumber:36↙inputrealpartandimaginarypartofcomplexnumber:4-10↙c1=(3+6i)c2=(4+-10i)根據(jù)先調(diào)試通過,最后完善的原那么,可對(duì)程序作必要的修改。將重載運(yùn)算符“<<〞函數(shù)修改如下:ostream&operator<<(ostream&output,Complex&c){output<<″(″<<c.real;if(c.imag>=0)output<<″+″;//虛部為正數(shù)時(shí),在虛部前加“+〞號(hào)output<<c.imag<<″i)″<<endl;//虛部為負(fù)數(shù)時(shí),在虛部前不加“+〞號(hào)returnoutput;}這樣,運(yùn)行時(shí)輸出的最后一行為c2=(4-10i)。通過本章前面幾節(jié)的討論,可以看到:在C++中,運(yùn)算符重載是很重要的、很有實(shí)用意義的。它使類的設(shè)計(jì)更加豐富多彩,擴(kuò)大了類的功能和使用范圍,使程序易于理解,易于對(duì)對(duì)象進(jìn)行操作,它表達(dá)了為用戶著想、方便用戶使用的思想。有了運(yùn)算符重載,在聲明了類之后,人們就可以像使用標(biāo)準(zhǔn)類型一樣來使用自己聲明的類。類的聲明往往是一勞永逸的,有了好的類,用戶在程序中就不必定義許多成員函數(shù)去完成某些運(yùn)算和輸入輸出的功能,使主函數(shù)更加簡(jiǎn)單易讀。好的運(yùn)算符重載能表達(dá)面向?qū)ο蟪绦蛟O(shè)計(jì)思想。在本章的例子中讀者應(yīng)當(dāng)注意到,在運(yùn)算符重載中使用引用(reference)的重要性。利用引用作為函數(shù)的形參可以在調(diào)用函數(shù)的過程中不是用傳遞值的方式進(jìn)行虛實(shí)結(jié)合,而是通過傳址方式使形參成為實(shí)參的別名,因此不生成臨時(shí)變量(實(shí)參的副本),減少了時(shí)間和空間的開銷。此外,如果重載函數(shù)的返回值是對(duì)象的引用時(shí),返回的不是常量,而是引用所代表的對(duì)象,它可以出現(xiàn)在賦值號(hào)的左側(cè)而成為左值(leftvalue),可以被賦值或參與其他操作(如保存cout流的當(dāng)前值以便能連續(xù)使用“<<〞輸出)。但使用引用時(shí)要特別小心,因?yàn)樾薷牧艘镁偷扔谛薷牧怂淼膶?duì)象。在C++中,某些不同類型數(shù)據(jù)之間可以自動(dòng)轉(zhuǎn)換,例如inti=6;i=7.5+i;編譯系統(tǒng)對(duì)7.5是作為double型數(shù)處理的,在求解表達(dá)式時(shí),先將6轉(zhuǎn)換成double型,然后與7.5相加,得到和為13.5,在向整型變量i賦值時(shí),將13.5轉(zhuǎn)換為整數(shù)13,然后賦給i。這種轉(zhuǎn)換是由C++編譯系統(tǒng)自動(dòng)完成的,用戶不需干預(yù)。這種轉(zhuǎn)換稱為隱式類型轉(zhuǎn)換。10.8不同類型數(shù)據(jù)間的轉(zhuǎn)換

10.8.1標(biāo)準(zhǔn)類型數(shù)據(jù)間的轉(zhuǎn)換C++還提供顯式類型轉(zhuǎn)換,程序人員在程序中指定將一種指定的數(shù)據(jù)轉(zhuǎn)換成另一指定的類型,其形式為類型名(數(shù)據(jù))如int(89.5)其作用是將89.5轉(zhuǎn)換為整型數(shù)89。對(duì)于用戶自己聲明的類型,編譯系統(tǒng)并不知道怎樣進(jìn)行轉(zhuǎn)換。解決這個(gè)問題的關(guān)鍵是讓編譯系統(tǒng)知道怎樣去進(jìn)行這些轉(zhuǎn)換,需要定義專門的函數(shù)來處理。轉(zhuǎn)換構(gòu)造函數(shù)(conversionconstructorfunction)的作用是將一個(gè)其他類型的數(shù)據(jù)轉(zhuǎn)換成一個(gè)類的對(duì)象。先回憶一下以前學(xué)習(xí)過的幾種構(gòu)造函數(shù):默認(rèn)構(gòu)造函數(shù)。以Complex類為例,函數(shù)原型的形式為Complex();//沒有參數(shù)用于初始化的構(gòu)造函數(shù)。函數(shù)原型的形式為Complex(doubler,doublei);//形參表列中一般有兩個(gè)以上參數(shù)用于復(fù)制對(duì)象的復(fù)制構(gòu)造函數(shù)。函數(shù)原型的形式為10.8.2轉(zhuǎn)換構(gòu)造函數(shù)Complex(Complex&c);//形參是本類對(duì)象的引用現(xiàn)在又要介紹一種新的構(gòu)造函數(shù)——轉(zhuǎn)換構(gòu)造函數(shù)。轉(zhuǎn)換構(gòu)造函數(shù)只有一個(gè)形參,如Complex(doubler){real=r;imag=0;}其作用是將double型的參數(shù)r轉(zhuǎn)換成Complex類的對(duì)象,將r作為復(fù)數(shù)的實(shí)部,虛部為0。用戶可以根據(jù)需要定義轉(zhuǎn)換構(gòu)造函數(shù),在函數(shù)體中告訴編譯系統(tǒng)怎樣去進(jìn)行轉(zhuǎn)換。在類體中,可以有轉(zhuǎn)換構(gòu)造函數(shù),也可以沒有轉(zhuǎn)換構(gòu)造函數(shù),視需要而定。以上幾種構(gòu)造函數(shù)可以同時(shí)出現(xiàn)在同一個(gè)類中,它們是構(gòu)造函數(shù)的重載。編譯系統(tǒng)會(huì)根據(jù)建立對(duì)象時(shí)給出的實(shí)參的個(gè)數(shù)與類型選擇形參與之匹配的構(gòu)造函數(shù)。使用轉(zhuǎn)換構(gòu)造函數(shù)將一個(gè)指定的數(shù)據(jù)轉(zhuǎn)換為類對(duì)象的方法如下:〔1〕先聲明一個(gè)類。〔2〕在這個(gè)類中定義一個(gè)只有一個(gè)參數(shù)的構(gòu)造函數(shù),參數(shù)的類型是需要轉(zhuǎn)換的類型,在函數(shù)體中指定轉(zhuǎn)換的方法?!?〕在該類的作用域內(nèi)可以用以下形式進(jìn)行類型轉(zhuǎn)換:類名(指定類型的數(shù)據(jù))就可以將指定類型的數(shù)據(jù)轉(zhuǎn)換為此類的對(duì)象。不僅可以將一個(gè)標(biāo)準(zhǔn)類型數(shù)據(jù)轉(zhuǎn)換成類對(duì)象,也可以將另一個(gè)類的對(duì)象轉(zhuǎn)換成轉(zhuǎn)換構(gòu)造函數(shù)所在的類對(duì)象。如可以將一個(gè)學(xué)生類對(duì)象轉(zhuǎn)換為教師類對(duì)象,可以在Teacher類中寫出下面的轉(zhuǎn)換構(gòu)造函數(shù):Teacher(Student&s){num=s.num;strcpy(name,);sex=s.sex;}但應(yīng)注意:對(duì)象s中的num,name,sex必須是公用成員,否那么不能被類外引用。用轉(zhuǎn)換構(gòu)造函數(shù)可以將一個(gè)指定類型的數(shù)據(jù)轉(zhuǎn)換為類的對(duì)象。但是不能反過來將一個(gè)類的對(duì)象轉(zhuǎn)換為一個(gè)其他類型的數(shù)據(jù)(例如將一個(gè)Complex類對(duì)象轉(zhuǎn)換成double類型數(shù)據(jù))。C++提供類型轉(zhuǎn)換函數(shù)(typeconversionfunction)來解決這個(gè)問題。類型轉(zhuǎn)換函數(shù)的作用是將一個(gè)類的對(duì)象轉(zhuǎn)換成另一類型的數(shù)據(jù)。如果已聲明了一個(gè)Complex類,可以在Complex類中這樣定義類型轉(zhuǎn)換函數(shù):operatordouble(){returnreal;}類型轉(zhuǎn)換函數(shù)的一般形式為10.8.3類型轉(zhuǎn)換函數(shù)operator類型名(){實(shí)現(xiàn)轉(zhuǎn)換的語句}在函數(shù)名前面不能指定函數(shù)類型,函數(shù)沒有參數(shù)。其返回值的類型是由函數(shù)名中指定的類型名來確定的。類型轉(zhuǎn)換函數(shù)只能作為成員函數(shù),因?yàn)檗D(zhuǎn)換的主體是本類的對(duì)象。不能作為友元函數(shù)或普通函數(shù)。從函數(shù)形式可以看到,它與運(yùn)算符重載函數(shù)相似,都是用關(guān)鍵字operator開頭,只是被重載的是類型名。double類型經(jīng)過重載后,除了原有的含義外,還獲得新的含義(將一個(gè)Complex類對(duì)象轉(zhuǎn)換為double類型數(shù)據(jù),并指定了轉(zhuǎn)換方法)。這樣,編譯系統(tǒng)不僅能識(shí)別原有的double型數(shù)據(jù),而且還會(huì)把Complex類對(duì)象作為double型數(shù)據(jù)處理。那么程序中的Complex類對(duì)具有雙重身份,既是Complex類對(duì)象,又可作為double類型數(shù)據(jù)。Complex類對(duì)象只有在需要時(shí)才進(jìn)行轉(zhuǎn)換,要根據(jù)表達(dá)式的上下文來決定。轉(zhuǎn)換構(gòu)造函數(shù)和類型轉(zhuǎn)換運(yùn)算符有一個(gè)共同的功能:當(dāng)需要的時(shí)候,編譯系統(tǒng)會(huì)自動(dòng)調(diào)用這些函數(shù),建立一個(gè)無名的臨時(shí)對(duì)象(或臨時(shí)變量)。例10.9使用類型轉(zhuǎn)換函數(shù)的簡(jiǎn)單例子。#include<iostream>usingnamespacestd;classComplex{public:Complex(){real=0;imag=0;}Complex(doubler,doublei){real=r;imag=i;}operatordouble(){returnreal;}//類型轉(zhuǎn)換函數(shù)private:doublereal;doubleimag;};intmain(){Complexc1(3,4),c2(5,-10),c3;doubled;d=2.5+c1;//要求將一個(gè)double數(shù)據(jù)與Complex類數(shù)據(jù)相加cout<<d<<endl;return0;}分析:(1)如果在Complex類中沒有定義類型轉(zhuǎn)換函數(shù)operatordouble,程序編譯將出錯(cuò)。(2)如果在main函數(shù)中加一個(gè)語句:c3=c2;由于賦值號(hào)兩側(cè)都是同一類的數(shù)據(jù),是可以合法進(jìn)行賦值的,沒有必要把c2轉(zhuǎn)換為double型數(shù)據(jù)。(3)如果在Complex類中聲明了重載運(yùn)算符“+〞函數(shù)作為友元函數(shù):Complexoperator+(Complexc1,Complexc2)//定義運(yùn)算符“+〞重載函數(shù){returnComplex(c1.real+c2.real,c1.imag+c2.imag);}假設(shè)在m

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論