華中科技大學(xué)C++課件第三章類和對象_第1頁
華中科技大學(xué)C++課件第三章類和對象_第2頁
華中科技大學(xué)C++課件第三章類和對象_第3頁
華中科技大學(xué)C++課件第三章類和對象_第4頁
華中科技大學(xué)C++課件第三章類和對象_第5頁
已閱讀5頁,還剩48頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第3章類和對象

類是面向?qū)ο蟪绦蛟O(shè)計的核心,它實際上是由用戶定義的一種新的復(fù)雜數(shù)據(jù)類型。類是通過抽象數(shù)據(jù)類型ADT方法來實現(xiàn)的一種(數(shù)據(jù))類型,它是對某一類對象的抽象,而對象是某種類的一個實例,因此類和對象是密切相關(guān)的。類是將不同類型的數(shù)據(jù)和與這些數(shù)據(jù)相關(guān)的操作封裝在一起的集合體。因此,它具有更高的抽象性。實現(xiàn)了信息的隱藏和封裝(Encapsulation)。

我們生活在科學(xué)技術(shù)飛速發(fā)展的現(xiàn)代化社會,需要了解和處理的事情太多、太復(fù)雜。為了減少必須了解處理的事情,我們是在某一程度的細(xì)節(jié)中生活的,也就是說,為了便于達(dá)到某種目的,在某種程度上必須要隱藏一些與此目的無關(guān)緊要的具體細(xì)節(jié)。例如在現(xiàn)實生活中人們通常把電視看成一種娛樂和獲取信息的工具來使用,不會考慮它的內(nèi)部結(jié)構(gòu)和工作原理,即將“制造電視機(jī)”和“使用電視機(jī)”區(qū)別開來。“制造電視”需要具備電視制造技術(shù)的專門人才來完成。在面向?qū)ο蟮挠嬎銠C(jī)世界中,這種細(xì)節(jié)程度的數(shù)據(jù)隱藏就叫抽象。在OOP中也有分工明確的兩種編程。一種是標(biāo)準(zhǔn)類庫的設(shè)計,這是由搞面向?qū)ο笳Z言系統(tǒng)的軟件專門人員來完成。另一種是面向?qū)ο髴?yīng)用程序設(shè)計,它是由從事計算機(jī)應(yīng)用的各類專業(yè)人員完成?!?.1類的定義1.類的定義格式:類的定義具有如下標(biāo)準(zhǔn)化格式:

class類名

類頭{ private:

數(shù)據(jù)成員或成員函數(shù)的說明

protected:類體

數(shù)據(jù)成員或成員函數(shù)的說明

public:

數(shù)據(jù)成員或成員函數(shù)的說明};<各成員函數(shù)的實現(xiàn)(定義部分)>說明:(1)類的定義格式分為說明部分和實現(xiàn)部分。說明部分是用來描述該類中的成員,包括數(shù)據(jù)成員的說明和成員函數(shù)的說明,成員函數(shù)是用來對數(shù)據(jù)成員進(jìn)行操作的,又稱為“方法”。實現(xiàn)部分是用來定義各種成員函數(shù)的,以描述這些成員函數(shù)是如何實現(xiàn)對數(shù)據(jù)成員的操作??傊?,說明部分將告訴編程者這個類是“干什么”的,而實現(xiàn)部分是告知“怎么干”的。(2)類的說明部分由類頭和類體兩部分組成,類頭有關(guān)鍵字class和類名組成,類名是由編程者啟用的一種標(biāo)識符,有些軟件開發(fā)商如Microsoft公司,用‘C’(Class)開頭的字符串作為類名,也有的用大寫字母‘T’(Type)開頭的字符串作為類名,以便與對象名、函數(shù)名區(qū)別。開始的字符串作為類名,以便與對象名、函數(shù)名區(qū)別。類頭是用來向編譯系統(tǒng)聲明定義了一個新的類型,而類體是對類的組織形式進(jìn)行具體的描述。由訪問限制符(private、protected、public)和數(shù)據(jù)成員、成員函數(shù)組成,整個類體用一對大括號包圍起來,完整地表達(dá)對類的描述。教材p347

classDate{//tdate.hpublic://三個公有成員函數(shù)。

voidSetDate(inty=2000,

intm=1,intd=1);

int

IsLeapYear(); voidPrintDate();private:

intyear,month,day;//三個私有數(shù)據(jù)成員。};日期類Date的實現(xiàn)部分為:voidDate::SetDate(inty,intm,

intd){year=y;month=m;day=d; }int

Date::IsLeapYear()//判斷該年是否為閏年。{return(year%4==0&&year%100!=0)||(year%400==0);}voidDate::PrintDate()//顯示年、月、日的具體值。{cout<<year<<","<<month<<","<<day<<endl;}例如,用類定義一個關(guān)于日期的抽象數(shù)據(jù)類型ADT(AbstractDataType)。日期類取類名Date,能設(shè)置年、月、日的具體值,并能判斷該年是否為閏年,還能顯示年、月、日的具體值。日期類Date的說明部分為:(3)類由數(shù)據(jù)和函數(shù)組成,稱為類的成員,因此,類有兩種成員:數(shù)據(jù)成員和成員函數(shù)。成員函數(shù)又稱為“方法”(mathod)。本例中Date類共有6個成員,其中,三個私有數(shù)據(jù)成員,三個公有成員函數(shù)。(4)通常習(xí)慣上將類定義的說明部分或者整個定義部分(包含實現(xiàn)部分)放到一個頭文件中。例如,可將前面定義的類Date放到一個名為tdate.h的頭文件中。在需要引用Date類的源程序的開頭處寫上:#include"tdate.h"則tdate.h的全部內(nèi)容將嵌入到這條語句的位置上。//p1101.cpp教材p348#include<iostream.h>#include"tdate.h"voidmain(){Datedate1,date2;//定義日期類Date的兩個對象date1和date2。date1.SetDate(2000,5,4);//給對象date1設(shè)置年、月、日的具體值。

date2.SetDate(2000,4,9);//給對象date2設(shè)置年、月、日的具體值。

intleap=date1.IsLeapYear();//判斷對象date1的年份是否為閏年。

cout<<"LEAP="<<leap<<endl;//輸出判斷結(jié)果。

date1.PrintDate();//顯示對象date1年、月、日的具體值。

date2.PrintDate();//顯示對象date2年、月、日的具體值。}

(5)class允許隱藏內(nèi)部成員。它是依靠類定義中的三個訪問限制符public、private、protected來確定隱藏的程度,它們將類體劃分成三大部分。圖3.1形象地描繪了這三部分的區(qū)別。

class

protected:

private:

public:

圖10.1三種訪問限制符的區(qū)別

以public:開頭的程序部分稱為公有部分。

以private:開頭的程序部分稱為私有部分。以protected:開頭的程序部分稱為保護(hù)部分。

(6)類的定義只是定義了某種類的組織形式,即定義了一個新的class類型,相當(dāng)于ANSIC中的結(jié)構(gòu)體定義。編譯系統(tǒng)并不給class類型的每個數(shù)據(jù)成員分配內(nèi)存空間。

2.訪問限制符public、private、protected它們將類體分為三個部分,每一部分都可以有數(shù)據(jù)成員和成員函數(shù),也可以只有數(shù)據(jù)成員或成員函數(shù),但不同的訪問限制符規(guī)定了該部分所具有的訪問權(quán)限。(1)Public指定的為公有部分是透明的,它的數(shù)據(jù)成員和成員函數(shù)是開放的,既可以由本類的成員函數(shù)訪問,也可有程序的其他部分直接訪問。例如允許該類的對象去直接訪問它的公有部分即編寫成“對象名.公有成員名”的形式。(2)Private指定的為私有部分象一個黑盒子,完全是隱藏的,它只能由本類的成員函數(shù)訪問,不允許程序其他部分訪問,即在成員函數(shù)體內(nèi)直呼其名地寫出私有成員名,如在日期類Date的SetDate()成員函數(shù)體內(nèi),可以直接寫:year=y;month=m;day=d;”等語句。但是,不允許程序其他部分直接訪問,例如不允許該類的對象去直接訪問它的私有部分,即不允許編寫成“對象名.私有成員”的形式。例如在main()函數(shù)內(nèi),用該類的對象去直接訪問私有數(shù)據(jù)成員,即如下都是非法的:

date1.day=6;date1.month=12;date1.year=1999;

cout<<date1.day;(3)protected指定的保護(hù)部分是半透明的,它可由本類成員函數(shù)或它的派生類成員函數(shù)直接訪問,但也不允許程序其他部分直接訪問它。保護(hù)部分主要用于類的繼承,將在后面章節(jié)討論。(4)通??偸菍?shù)據(jù)成員指定為私有的以實現(xiàn)數(shù)據(jù)隱藏,這些數(shù)據(jù)成員是用來描述該類對象的屬性,編程者無法直接訪問它們而隱藏起來。而將成員函數(shù)指定為公有的,作為該類對象訪問私有數(shù)據(jù)成員的一個接口界面,即對象訪問私有數(shù)據(jù)成員的一條消息通路提供給外界使用。因此私有數(shù)據(jù)只能通過公有成員函數(shù)訪問,從而隱藏了處理這些數(shù)據(jù)的實現(xiàn)細(xì)節(jié),使得類對數(shù)據(jù)的描述和類提供給外部世界來處理數(shù)據(jù)的界面這兩件事情互相獨立,這就給出了面向?qū)ο蟮闹匾匦?,使得一個類的用戶唯一需要做的事情就是訪問類的界面。正如圖10.2所示:

Date類

public:private:year

SetDate()monthday

IsLeapYear()Protected:

Print()

圖10.2Date類的描述例程10.2(p350)用類定義一個計數(shù)器的抽象數(shù)據(jù)類型ADT(AbstractDataType)。計數(shù)器允許取值范圍為0~4294967295的正整數(shù),可進(jìn)行的操作是計數(shù)器加1、減1和讀計數(shù)器的值。其類的定義如下:

#include<iostream.h>classCounter{public:Counter()//Counter類的構(gòu)造函數(shù)。 {value=0;//初始化數(shù)據(jù)成員值。cout<<"Constructorcalled!\n";//輸出顯示調(diào)用了本構(gòu)造函數(shù)的信息。}

voidIncrement()//在允許取值范圍內(nèi)計數(shù)器加1。 {if(value<4294967295)value++;} voidDecrement()//當(dāng)計數(shù)器的數(shù)據(jù)成員值不為0時減1。 {if(value>0)value--;}unsignedReadValue()//讀計數(shù)器的值{returnvalue;}~Counter()//Counter類的析構(gòu)函數(shù)。{cout<<"Destructorcalled!\n";}//只輸出調(diào)用了本析構(gòu)函數(shù)的信息,其它什么也不做。

private: unsignedvalue;//Counter類的私有數(shù)據(jù)成員。};

voidmain()//Counter類的測試程序。{

Counterc1,c2;//定義了Counter類的兩個對象c1和c2。

for(inti=1;i<=6;i++){ c1.Increment();//在第1個for語句的循環(huán)體內(nèi)6次向

對象c1發(fā)送增量運算的消息。

cout<<"valueofc1="<<c1.ReadValue()<<endl;//每循環(huán)一次,顯示對象c1的計數(shù)值。

c2.Increment();//同樣6次向?qū)ο骳2發(fā)送增量運算的消

息。

}

cout<<"Afterloop,valueofc2="<<c2.ReadValue()<<endl;//循環(huán)完成后,顯示對象c2的計數(shù)值。

for(i=1;i<=5;i++) c2.Decrement();//在第2個for語句的循環(huán)體內(nèi)5次向?qū)ο骳2

發(fā)送減量運算的消息。cout<<"Finalvalueofc1="<<c1.ReadValue()<<",valueofc2="<<c2.ReadValue()<<endl;}//顯示對象c1和c2最終的計數(shù)值。

該程序的輸出結(jié)果:Constructorcalled!Constructorcalled!valueofc1=1valueofc1=2valueofc1=3valueofc1=4valueofc1=5valueofc1=6Afterloop,valueofc2=6Finalvalueofc1=6,valueofc2=1Destructorcalled!Destructorcalled!

3.?dāng)?shù)據(jù)成員:如前所述,類的定義與結(jié)構(gòu)體的定義一樣,僅僅定義了類的組織形式,給出了一個新的class類型,編譯系統(tǒng)并不給類的每個數(shù)據(jù)成員分配具體的內(nèi)存空間。數(shù)據(jù)成員既可以放在公有部分稱為公有數(shù)據(jù)成員,又可以放在私有或保護(hù)部分稱為私有或保護(hù)數(shù)據(jù)成員。它們的定義格式都是:

<類型>數(shù)據(jù)成員名;(1)數(shù)據(jù)成員只有<類型>說明,而無<存儲類>說明,所以將類的數(shù)據(jù)成員說明為auto、register和extern型都是無意義的。

(2)在類體中不允許對所定義的數(shù)據(jù)成員進(jìn)行初始化。例如,下面的定義都是錯誤的:classCounter{public:...private: unsignedvalue=0;//error};classDate{public:

...private:

intyear(1999),month(9),day(16);//error};(3)數(shù)據(jù)成員的類型可以是基本數(shù)據(jù)類型(char、int、...、double等)和復(fù)雜數(shù)據(jù)類型(數(shù)組、指針、引用、...、結(jié)構(gòu)變量等),或已經(jīng)定義了的類對象。當(dāng)另一個類的對象作為這個類的成員時,稱為“對象成員”,這另一個類必須預(yù)先定義好。例如:(教材p352,參見p52exg.cpp)classN{public:

...};//不能采用先聲明,后定義的形式。”classN;”classM{public:

...

private:Nn;//n是N類的對象};

4.成員函數(shù)(MemberFunction):類體(即緊跟類頭后一對大括號所包圍的程序部分)中不僅定義了該類的對象所具有的數(shù)據(jù)結(jié)構(gòu),還定義了對該類對象進(jìn)行操作的成員函數(shù)(方法),其定義格式如下:

<返回類型>[<類名>::]成員函數(shù)名函數(shù)頭(類型

參數(shù)1,...,類型

參數(shù)n){...

...

...}

函數(shù)體(1)所有成員函數(shù)都必須在類體內(nèi)用函數(shù)原型加以聲明。而成員函數(shù)的定義(方法的實現(xiàn)部分)則較靈活,既可在類體外定義,也可在類體內(nèi)定義。在類體外定義成員函數(shù)時,必須用類名加作用域運算符’::’來指明所定義的成員函數(shù)屬于哪個類;在類體內(nèi)定義的成員函數(shù),其函數(shù)頭可不寫

[<類名>::]。

(2)在類體內(nèi)定義成員函數(shù)時,編譯系統(tǒng)自動地將成員函數(shù)當(dāng)作內(nèi)聯(lián)函數(shù)處理,其函數(shù)頭前不必寫關(guān)鍵字”inline”。例如Counter類中的Increment()、Decrement()和

ReadValue()都是內(nèi)聯(lián)函數(shù)。若是類體外定義的成員函數(shù),必須用關(guān)鍵字”inline”指明它為內(nèi)聯(lián)函數(shù)。(3)在定義了類的對象后,才可以用如下格式調(diào)用(公有)成員函數(shù):對象名.成員函數(shù)名(實參表);例如:

Counterc1,c2;c1.Increment();

c2.Decrement();

(4)成員函數(shù)與普通函數(shù)一樣,可設(shè)置參數(shù)的默認(rèn)值(缺省值Default)。

§11.2對象的定義:定義一個類就相當(dāng)于創(chuàng)建了一個新的class類型。要使用類,還必須用已經(jīng)定義的類去說明它的實例變量(對象)。在C++中,class類型一旦被定義,它的實例變量(對象)就能被創(chuàng)建、初始化、并定義指針變量指向它。在程序中,該類名就可以象基本數(shù)據(jù)類型‘int’;、...、‘double’等一樣使用,用來定義具體的實例變量(對象)。例如:Datedate1,date2,date[31],*pdate;Counterc1,c2,*pc;

1.對象的定義格式:在定義好稱之為“類名”的一個類以后,就可以用如下格式定義它的對象:<存儲類><類名><對象名表>;<對象名表>中可以有一個或多個對象名,若為多個對象名時用逗號分隔開。對象名可以是一般對象名(如上例中Date、Counter為類名,date1、date2為Date類的兩個一般對象名,c1、c2為Counter類的一般對象),也可以是對象數(shù)組名(如date[31]是由31個Date類的對象有序排列成date[0]、date[1]、...、date[30]等組成的集合,取對象數(shù)組名為date),還可以是指向該類對象的指針名或?qū)υ擃悓ο蟮囊妹?。例如:Datedate1,&Rdate=date1;Counterc1,&Rc=c1;

2.指向?qū)ο蟮闹羔槪ê喎Q“對象指針”):(1)對象指針的定義格式:<存儲類><類名>指針名;例如:Counterc1,c2,*pc;這里所說的<存儲類>是指針變量本身的存儲類型,與ANSIC標(biāo)準(zhǔn)一樣,有extern型、static型、auto型等。而auto的說明經(jīng)常缺省,extern在定義時不寫,聲明時必須寫。順便指出,例中只定義了一個對象指針pc,但pc并沒有定向,還必須通過初始化或賦值操作將已存在的對象地址賦給它。即pc=&c1;另外,在C++中對象指針可作為另一個類的成員,此時的對象指針是沒有<存儲類>說明的。

(2)只要一個類已經(jīng)聲明(可以沒有定義),則指向該類的對象指針或該類對象的引用都可作為另一個類的成員。例如:

#include<iostream.h>//p52xg1.cppclassM;classN{private:

intid;public:M*pm;

N(inti){id=i;}

int

GetName(){returnid;}};classM{public:

intvalue;

M(intv){value=v;}M(){value=0;}

int

GetValue(){returnvalue;}};

voidmain(){Mm1(6),m2(8);Nn(4);n.pm=&m2;

cout<<"valueofm1="<<m1.GetValue()<<endl;

cout<<"valuepointedbymemberpmofn="<<n.pm->value<<endl;

cout<<"idofn="<<n.GetName()<<endl;}程序的輸出結(jié)果:valueofm1=6valuepointedbymemberpmofn=8idofn=43.訪問類對象成員的方法:如前所述,類有兩種成員,即數(shù)據(jù)成員和成員函數(shù)。每個對象都是類的一個實例,都具有自己的數(shù)據(jù)成員值,而該類所有對象的數(shù)據(jù)結(jié)構(gòu)及其訪問權(quán)限卻是由它的類統(tǒng)一定義的。因此同一個類所創(chuàng)建的對象,其數(shù)據(jù)結(jié)構(gòu)都是相同的,類中的成員函數(shù)是共享的,而不同對象的數(shù)據(jù)成員值可以是不相同的。例如,對已經(jīng)定義的Counter類可用如下語句定義對象和對象指針:

Counterc1,c2,*pc;對象c1、c2都具有各自的value值,但value的數(shù)據(jù)類型(unsigned)和訪問權(quán)限(private)則由Counter類統(tǒng)一定義。由于它是私有數(shù)據(jù)成員,程序的其他部分不能直接訪問它,必須通過公有部分的成員函數(shù)。c1.value;//error不能直接訪問私有數(shù)據(jù)成員c1.ReadValue();//用公有成員函數(shù)訪問私有數(shù)據(jù)成員

(1)數(shù)據(jù)成員的訪問方法:如上所述,對于私有數(shù)據(jù)成員只能通過公有成員函數(shù)才能訪問它。而公有數(shù)據(jù)成員可直接訪問它,其格式為:

對象名.公有數(shù)據(jù)成員名或

對象指針名->公有數(shù)據(jù)成員名其中<對象指針名>應(yīng)與對象屬于相同的class類型,且必須通過初始化或賦值操作將已存在的對象地址賦給它。當(dāng)然也可以通過成員函數(shù)訪問它。Point類的定義寫成如下程序代碼,并把它存放在tpoint.h的頭文件中:

(P358)classPoint{public://四個公有成員函數(shù)。

voidSetPoint(inta,intb);//設(shè)定點的X、Y坐標(biāo)值。int

ReadX(){returnx;}//讀取點的X坐標(biāo)值。int

ReadY(){returny;}//讀取點的Y坐標(biāo)值。voidMove(int

xOffset,

int

yOffset);//計算點移動后的X、Y坐標(biāo)值。

intx,y;//兩個公有數(shù)據(jù)成員x和y。};voidPoint::SetPoint(inta,intb){x=a;y=b;}voidPoint::Move(int

xOffset,

int

yOffset){x+=xOffset;y+=yOffset;}例11.5編寫Point類的測試程序。#include<iostream.h>#include"tpoint.h"voidmain(){Pointp1,p2;//定義Point類的兩個對象p1和p2。Point&ref=p1,*ptr=&p2;//還定義了一個對對象p1的引用ref和指向?qū)ο髉2的對象指針ptr。 p1.x=3;p1.y=5;

//可用對象名直接訪問公有數(shù)據(jù)成員,給p1

點設(shè)定X、Y坐標(biāo)值。

p2.SetPoint(8,10);//也可用公有成員函數(shù)SetPoint()給p1點設(shè)定X、Y坐標(biāo)值。

p1.Move(2,1);//調(diào)用公有成員函數(shù)Move(),移動p1點。

p2.Move(1,-2);//調(diào)用公有成員函數(shù)Move(),移動p2點。

cout<<"x1="<<ref.x<<","<<"y1="<<ref.y<<endl;//使用對象引用ref代替p1直接訪問它的公有數(shù)據(jù)成員x和y。

cout<<"x2="<<ptr->x<<","<<"y2="<<ptr->y<<endl;//使用對象指針ptr代替p2直接訪問它的公有數(shù)據(jù)成員x和y。}

該程序的輸出結(jié)果:x1=5,y1=6x2=9,y2=8(2)成員函數(shù)的訪問方法:訪問成員函數(shù)的格式:

對象名.公有成員函數(shù)名(參數(shù)表);

對象指針名->公有成員函數(shù)名(參數(shù)表);

其中<對象指針名>應(yīng)與對象屬于相同的class類型,且必須通過定向操作指向了已存在的對象。(3)通過引用對象訪問成員的方法。引用對象可用來代替被引用的對象名訪問成員,其格式:

引用對象名.公有數(shù)據(jù)成員名或

引用對象名.公有成員函數(shù)名(參數(shù)表)§10.3對象的初始化:構(gòu)造函數(shù)和析構(gòu)函數(shù)是在類體中說明的兩種特殊的成員函數(shù)。1.構(gòu)造函數(shù):C++中“類”只定義了一組對象的類型。要使用這個類還必須用“類”說明它的對象,每個對象中的數(shù)據(jù)成員還必須賦初值,這些功能都是由構(gòu)造函數(shù)完成的。(1)構(gòu)造函數(shù)是一種特殊的成員函數(shù),其定義格式和其他成員函數(shù)相同,只是它以類名作為函數(shù)名,例如Counter類的構(gòu)造函數(shù)為Counter(),且不能指定返回類型和顯式的返回值,連void都不能寫,即無返回類型。若某類定義了構(gòu)造函數(shù),則每當(dāng)該類的對象創(chuàng)建時,編譯系統(tǒng)為它的對象分配內(nèi)存空間,并自動調(diào)用構(gòu)造函數(shù)初始化所創(chuàng)建的對象,從而確保每個對象自動地初始化。例如:

Counterc1;編譯系統(tǒng)為對象c1的每個數(shù)據(jù)成員(value)分配內(nèi)存空間,并調(diào)用構(gòu)造函數(shù)Counter()自動地初始化對象c1的value值設(shè)置為0。(2)構(gòu)造函數(shù)只完成新對象的初始化工作,不執(zhí)行對象的主要任務(wù)。即在類創(chuàng)建新對象時,為對象分配內(nèi)存空間,給數(shù)據(jù)成員賦初值。(3)幾乎每個類都定義了多個構(gòu)造函數(shù),以適應(yīng)創(chuàng)建對象時,對象的參數(shù)具有不同個數(shù)的情況,即構(gòu)造函數(shù)可重載。P360,例10.6#include<iostream.h>classComplex{public:Complex(doublereal,doubleimag);//Constructor(1),一般構(gòu)造函數(shù)。

Complex(void);//Constructor(2),無參數(shù)構(gòu)造函數(shù)。

Complex(constComplex&c); //Constructor(3),復(fù)制構(gòu)造函數(shù)

Complex(doublereal);//Constructor(4),類型轉(zhuǎn)換構(gòu)造函數(shù)。

voidprint(inti);private:doublereal,imag;};//一般構(gòu)造函數(shù),用兩個實數(shù)分別給新創(chuàng)建對象的

兩個數(shù)據(jù)成員賦初值。

Complex::Complex(doubler,doublei){real=r;imag=i;

cout<<"Constructor(1)called:real="<<real<<",imag="<<imag<<endl;//輸出被調(diào)用的提示信息。}//無參數(shù)構(gòu)造函數(shù),創(chuàng)建新對象并將它的數(shù)據(jù)成員

都設(shè)定成0。Complex::Complex(void){real=0.0;imag=0.0;cout<<"Constructor(2)called:real="<<real<<",imag="<<imag<<endl;//輸出被調(diào)用的提示信息。}/*復(fù)制構(gòu)造函數(shù),把已存在對象的每個數(shù)據(jù)成員

都對應(yīng)賦值給新創(chuàng)建對象的數(shù)據(jù)成員,即對新

創(chuàng)建對象進(jìn)行“位模式拷貝”。*/Complex::Complex(constComplex&c){real=c.real;imag=c.imag;

cout<<"Constructor(3)called:real="<<real<<",imag="<<imag<<endl;//輸出被調(diào)用的提示信息。}//類型轉(zhuǎn)換構(gòu)造函數(shù),把一個實數(shù)轉(zhuǎn)換成虛數(shù)部分

為零的復(fù)數(shù)。Complex::Complex(doubler){real=r;imag=0.0;

cout<<"Constructor(4)called:real="<<real<<",imag="<<imag<<endl;//輸出被調(diào)用的提示信息。}//輸出顯示復(fù)數(shù)類對象的值,形參i用來表示對

象的序號。voidComplex::print(inti){if(imag<0)

cout<<"c"<<i<<"="<<real<<imag<<"i"<<endl;else

cout<<"c"<<i<<"="<<real<<"+"<<imag<<"i"<<endl;}voidmain(){Complexc1,c2(6,8),c3(5.6,7.9),\c4=c2;

c1.print(1);//輸出顯示復(fù)數(shù)類對象c1。c2.print(2);//輸出顯示復(fù)數(shù)類對象c2。

c3.print(3);//輸出顯示復(fù)數(shù)類對象c3。c4.print(4);//輸出顯示復(fù)數(shù)類對象c4。c1=Complex(1.2,3.4);//直接調(diào)用構(gòu)造函數(shù)。

c3=c2;//把復(fù)數(shù)類對象c2的每個數(shù)據(jù)成員值賦給c3。

c2=5;//調(diào)用類型轉(zhuǎn)換構(gòu)造函數(shù),把實數(shù)轉(zhuǎn)換成復(fù)數(shù)。

c1.print(1);//輸出顯示復(fù)數(shù)類對象c1。

c2.print(2);//輸出顯示復(fù)數(shù)類對象c2。c3.print(3);//輸出顯示復(fù)數(shù)類對象c3。c4.print(4);//輸出顯示復(fù)數(shù)類對象c4。}

該程序輸出結(jié)果:

Constructor(2)called:real=0,imag=0//創(chuàng)建c1,調(diào)用無參數(shù)構(gòu)造函數(shù)。

Constructor(1)called:real=6,imag=8//創(chuàng)建c2,調(diào)用一般構(gòu)造函數(shù)。

Constructor(1)called:real=5.6,imag=7.9//創(chuàng)建c3,調(diào)用一般構(gòu)造函數(shù)。

Constructor(3)called:real=6,imag=8//創(chuàng)建c4,調(diào)用復(fù)制構(gòu)造函數(shù)。c1=0+0i//執(zhí)行“c1.print(1);”語句。c2=6+8i//執(zhí)行“c2.print(2);”語句。

c3=5.6+7.9i//執(zhí)行“c3.print(3);”語句。

c4=6+8i//執(zhí)行“c4.print(4);”語句。Constructor(1):real=1.2,imag=3.4//執(zhí)行“c1=Complex(1.2,3.4);”。

Constructor(4)called:real=5,imag=0//執(zhí)行“c2=5;”。c1=1.2+3.4ic2=5+0ic3=6+8ic4=6+8i(4)通常在程序中不直接調(diào)用構(gòu)造函數(shù),可以在創(chuàng)建對象時顯式地調(diào)用構(gòu)造函數(shù)。(p266)例如,

Datetoday=Date(1998,4,9);Counterc1=Counter();將today定義為類Date的對象,并調(diào)用構(gòu)造函數(shù)Date(inty,intm,intday);初始化對象today的數(shù)據(jù)成員year,month,day。其格式為:

類名

對象名=構(gòu)造函數(shù)名(實參表);

由于“構(gòu)造函數(shù)名”就是“類名”,所以可用更簡單的形式:

類名

對象名(實參表);此時是在創(chuàng)建對象時,隱式地(自動地)調(diào)用構(gòu)造函數(shù)。

2.析構(gòu)函數(shù):它是構(gòu)造函數(shù)的配對物,與構(gòu)造函數(shù)一樣是與類同名的成員函數(shù),并在函數(shù)名前加上一個’~’以便與構(gòu)造函數(shù)相區(qū)別。例如:count.cpp中的析構(gòu)函數(shù)~Counter()。

(1)一個類只能有一個析構(gòu)函數(shù),且析構(gòu)函數(shù)沒有參數(shù)和返回值,它實現(xiàn)與構(gòu)造函數(shù)相反的功能。在刪除對象時執(zhí)行一些清理任務(wù),例如釋放對象所占用的內(nèi)存空間,有些對象可能還需做其他的事情,如當(dāng)撤消一個顯示窗口對象時,還需將它們從屏幕上清除掉。(2)對于用new創(chuàng)建的(動態(tài))對象,只有用delete撤消時編譯系統(tǒng)才調(diào)用析構(gòu)函數(shù)。

(3)如果編程者沒有給類定義析構(gòu)函數(shù),那么編譯系統(tǒng)將生成一個什么也不做的缺省析構(gòu)函數(shù)。例如,Complex類的缺省析構(gòu)函數(shù)為:

Complex::~Complex(){}//空函數(shù)有人會問為什么要把缺省析構(gòu)函數(shù)設(shè)計成什么都不做(對編程者來說)呢?因為只有這樣對于各種存儲類的對象,才能夠按照它本來的創(chuàng)建和撤消管理機(jī)制運行。例如,自動對象在程序運行期間,每當(dāng)遇到它的聲明時就創(chuàng)建它,當(dāng)離開它的作用域時就自動撤消它。這將在§10.6對象的存儲類中詳細(xì)講述。

(4)編譯系統(tǒng)自動調(diào)用構(gòu)造函數(shù)的次序和調(diào)用析構(gòu)函數(shù)的次序是相反的。為了驗證這一點,給Counter類新增加一個私有數(shù)據(jù)成員intwho;用來記錄所生成對象的序號,變?yōu)椋?/p>

#include<iostream.h>//countxu.cppclassCounter{public:

Counter(intid) {value=0;who=id;

cout<<"Object"<<who<<"initialized!\n";}

...~Counter() {cout<<"Object"<<who<<"destroyed!\n";}private: unsignedvalue;

intwho;};voidmain(){ Counterc1(1),c2(2);

cout<<“OK!\n”;}其輸出結(jié)果為:Object1initialized!Object2initialized!OK!Object2destroyed!Object1destroyed!3.構(gòu)造函數(shù)的種類:構(gòu)造函數(shù)可帶有各種類型的參數(shù),根據(jù)參數(shù)所具有的類型可將它分為如下四種:(1)無參數(shù)的構(gòu)造函數(shù):當(dāng)程序中寫有這樣的語句定義新對象時,如:voidmain(){Complexc1;...}則在Complex類中必須定義這樣一個構(gòu)造函數(shù),Complex::Complex(void){r

溫馨提示

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

最新文檔

評論

0/150

提交評論