版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第3章類(lèi)和對(duì)象
類(lèi)是面向?qū)ο蟪绦蛟O(shè)計(jì)的核心,它實(shí)際上是由用戶(hù)定義的一種新的復(fù)雜數(shù)據(jù)類(lèi)型。類(lèi)是通過(guò)抽象數(shù)據(jù)類(lèi)型ADT方法來(lái)實(shí)現(xiàn)的一種(數(shù)據(jù))類(lèi)型,它是對(duì)某一類(lèi)對(duì)象的抽象,而對(duì)象是某種類(lèi)的一個(gè)實(shí)例,因此類(lèi)和對(duì)象是密切相關(guān)的。類(lèi)是將不同類(lèi)型的數(shù)據(jù)和與這些數(shù)據(jù)相關(guān)的操作封裝在一起的集合體。因此,它具有更高的抽象性。實(shí)現(xiàn)了信息的隱藏和封裝(Encapsulation)。
我們生活在科學(xué)技術(shù)飛速發(fā)展的現(xiàn)代化社會(huì),需要了解和處理的事情太多、太復(fù)雜。為了減少必須了解處理的事情,我們是在某一程度的細(xì)節(jié)中生活的,也就是說(shuō),為了便于達(dá)到某種目的,在某種程度上必須要隱藏一些與此目的無(wú)關(guān)緊要的具體細(xì)節(jié)。例如在現(xiàn)實(shí)生活中人們通常把電視看成一種娛樂(lè)和獲取信息的工具來(lái)使用,不會(huì)考慮它的內(nèi)部結(jié)構(gòu)和工作原理,即將“制造電視機(jī)”和“使用電視機(jī)”區(qū)別開(kāi)來(lái)?!爸圃祀娨暋毙枰邆潆娨曋圃旒夹g(shù)的專(zhuān)門(mén)人才來(lái)完成。在面向?qū)ο蟮挠?jì)算機(jī)世界中,這種細(xì)節(jié)程度的數(shù)據(jù)隱藏就叫抽象。在OOP中也有分工明確的兩種編程。一種是標(biāo)準(zhǔn)類(lèi)庫(kù)的設(shè)計(jì),這是由搞面向?qū)ο笳Z(yǔ)言系統(tǒng)的軟件專(zhuān)門(mén)人員來(lái)完成。另一種是面向?qū)ο髴?yīng)用程序設(shè)計(jì),它是由從事計(jì)算機(jī)應(yīng)用的各類(lèi)專(zhuān)業(yè)人員完成?!?.1類(lèi)的定義1.類(lèi)的定義格式:類(lèi)的定義具有如下標(biāo)準(zhǔn)化格式:
class類(lèi)名
類(lèi)頭{ private:
數(shù)據(jù)成員或成員函數(shù)的說(shuō)明
protected:類(lèi)體
數(shù)據(jù)成員或成員函數(shù)的說(shuō)明
public:
數(shù)據(jù)成員或成員函數(shù)的說(shuō)明};<各成員函數(shù)的實(shí)現(xiàn)(定義部分)>說(shuō)明:(1)類(lèi)的定義格式分為說(shuō)明部分和實(shí)現(xiàn)部分。說(shuō)明部分是用來(lái)描述該類(lèi)中的成員,包括數(shù)據(jù)成員的說(shuō)明和成員函數(shù)的說(shuō)明,成員函數(shù)是用來(lái)對(duì)數(shù)據(jù)成員進(jìn)行操作的,又稱(chēng)為“方法”。實(shí)現(xiàn)部分是用來(lái)定義各種成員函數(shù)的,以描述這些成員函數(shù)是如何實(shí)現(xiàn)對(duì)數(shù)據(jù)成員的操作??傊?,說(shuō)明部分將告訴編程者這個(gè)類(lèi)是“干什么”的,而實(shí)現(xiàn)部分是告知“怎么干”的。(2)類(lèi)的說(shuō)明部分由類(lèi)頭和類(lèi)體兩部分組成,類(lèi)頭有關(guān)鍵字class和類(lèi)名組成,類(lèi)名是由編程者啟用的一種標(biāo)識(shí)符,有些軟件開(kāi)發(fā)商如Microsoft公司,用‘C’(Class)開(kāi)頭的字符串作為類(lèi)名,也有的用大寫(xiě)字母‘T’(Type)開(kāi)頭的字符串作為類(lèi)名,以便與對(duì)象名、函數(shù)名區(qū)別。開(kāi)始的字符串作為類(lèi)名,以便與對(duì)象名、函數(shù)名區(qū)別。類(lèi)頭是用來(lái)向編譯系統(tǒng)聲明定義了一個(gè)新的類(lèi)型,而類(lèi)體是對(duì)類(lèi)的組織形式進(jìn)行具體的描述。由訪問(wèn)限制符(private、protected、public)和數(shù)據(jù)成員、成員函數(shù)組成,整個(gè)類(lèi)體用一對(duì)大括號(hào)包圍起來(lái),完整地表達(dá)對(duì)類(lèi)的描述。教材p347
classDate{//tdate.hpublic://三個(gè)公有成員函數(shù)。
voidSetDate(inty=2000,
intm=1,intd=1);
int
IsLeapYear(); voidPrintDate();private:
intyear,month,day;//三個(gè)私有數(shù)據(jù)成員。};日期類(lèi)Date的實(shí)現(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;}例如,用類(lèi)定義一個(gè)關(guān)于日期的抽象數(shù)據(jù)類(lèi)型ADT(AbstractDataType)。日期類(lèi)取類(lèi)名Date,能設(shè)置年、月、日的具體值,并能判斷該年是否為閏年,還能顯示年、月、日的具體值。日期類(lèi)Date的說(shuō)明部分為:(3)類(lèi)由數(shù)據(jù)和函數(shù)組成,稱(chēng)為類(lèi)的成員,因此,類(lèi)有兩種成員:數(shù)據(jù)成員和成員函數(shù)。成員函數(shù)又稱(chēng)為“方法”(mathod)。本例中Date類(lèi)共有6個(gè)成員,其中,三個(gè)私有數(shù)據(jù)成員,三個(gè)公有成員函數(shù)。(4)通常習(xí)慣上將類(lèi)定義的說(shuō)明部分或者整個(gè)定義部分(包含實(shí)現(xiàn)部分)放到一個(gè)頭文件中。例如,可將前面定義的類(lèi)Date放到一個(gè)名為tdate.h的頭文件中。在需要引用Date類(lèi)的源程序的開(kāi)頭處寫(xiě)上:#include"tdate.h"則tdate.h的全部?jī)?nèi)容將嵌入到這條語(yǔ)句的位置上。//p1101.cpp教材p348#include<iostream.h>#include"tdate.h"voidmain(){Datedate1,date2;//定義日期類(lèi)Date的兩個(gè)對(duì)象date1和date2。date1.SetDate(2000,5,4);//給對(duì)象date1設(shè)置年、月、日的具體值。
date2.SetDate(2000,4,9);//給對(duì)象date2設(shè)置年、月、日的具體值。
intleap=date1.IsLeapYear();//判斷對(duì)象date1的年份是否為閏年。
cout<<"LEAP="<<leap<<endl;//輸出判斷結(jié)果。
date1.PrintDate();//顯示對(duì)象date1年、月、日的具體值。
date2.PrintDate();//顯示對(duì)象date2年、月、日的具體值。}
(5)class允許隱藏內(nèi)部成員。它是依靠類(lèi)定義中的三個(gè)訪問(wèn)限制符public、private、protected來(lái)確定隱藏的程度,它們將類(lèi)體劃分成三大部分。圖3.1形象地描繪了這三部分的區(qū)別。
class
protected:
private:
public:
圖10.1三種訪問(wèn)限制符的區(qū)別
以public:開(kāi)頭的程序部分稱(chēng)為公有部分。
以private:開(kāi)頭的程序部分稱(chēng)為私有部分。以protected:開(kāi)頭的程序部分稱(chēng)為保護(hù)部分。
(6)類(lèi)的定義只是定義了某種類(lèi)的組織形式,即定義了一個(gè)新的class類(lèi)型,相當(dāng)于ANSIC中的結(jié)構(gòu)體定義。編譯系統(tǒng)并不給class類(lèi)型的每個(gè)數(shù)據(jù)成員分配內(nèi)存空間。
2.訪問(wèn)限制符public、private、protected它們將類(lèi)體分為三個(gè)部分,每一部分都可以有數(shù)據(jù)成員和成員函數(shù),也可以只有數(shù)據(jù)成員或成員函數(shù),但不同的訪問(wèn)限制符規(guī)定了該部分所具有的訪問(wèn)權(quán)限。(1)Public指定的為公有部分是透明的,它的數(shù)據(jù)成員和成員函數(shù)是開(kāi)放的,既可以由本類(lèi)的成員函數(shù)訪問(wèn),也可有程序的其他部分直接訪問(wèn)。例如允許該類(lèi)的對(duì)象去直接訪問(wèn)它的公有部分即編寫(xiě)成“對(duì)象名.公有成員名”的形式。(2)Private指定的為私有部分象一個(gè)黑盒子,完全是隱藏的,它只能由本類(lèi)的成員函數(shù)訪問(wèn),不允許程序其他部分訪問(wèn),即在成員函數(shù)體內(nèi)直呼其名地寫(xiě)出私有成員名,如在日期類(lèi)Date的SetDate()成員函數(shù)體內(nèi),可以直接寫(xiě):year=y;month=m;day=d;”等語(yǔ)句。但是,不允許程序其他部分直接訪問(wèn),例如不允許該類(lèi)的對(duì)象去直接訪問(wèn)它的私有部分,即不允許編寫(xiě)成“對(duì)象名.私有成員”的形式。例如在main()函數(shù)內(nèi),用該類(lèi)的對(duì)象去直接訪問(wèn)私有數(shù)據(jù)成員,即如下都是非法的:
date1.day=6;date1.month=12;date1.year=1999;
cout<<date1.day;(3)protected指定的保護(hù)部分是半透明的,它可由本類(lèi)成員函數(shù)或它的派生類(lèi)成員函數(shù)直接訪問(wèn),但也不允許程序其他部分直接訪問(wèn)它。保護(hù)部分主要用于類(lèi)的繼承,將在后面章節(jié)討論。(4)通??偸菍?shù)據(jù)成員指定為私有的以實(shí)現(xiàn)數(shù)據(jù)隱藏,這些數(shù)據(jù)成員是用來(lái)描述該類(lèi)對(duì)象的屬性,編程者無(wú)法直接訪問(wèn)它們而隱藏起來(lái)。而將成員函數(shù)指定為公有的,作為該類(lèi)對(duì)象訪問(wèn)私有數(shù)據(jù)成員的一個(gè)接口界面,即對(duì)象訪問(wèn)私有數(shù)據(jù)成員的一條消息通路提供給外界使用。因此私有數(shù)據(jù)只能通過(guò)公有成員函數(shù)訪問(wèn),從而隱藏了處理這些數(shù)據(jù)的實(shí)現(xiàn)細(xì)節(jié),使得類(lèi)對(duì)數(shù)據(jù)的描述和類(lèi)提供給外部世界來(lái)處理數(shù)據(jù)的界面這兩件事情互相獨(dú)立,這就給出了面向?qū)ο蟮闹匾匦?,使得一個(gè)類(lèi)的用戶(hù)唯一需要做的事情就是訪問(wèn)類(lèi)的界面。正如圖10.2所示:
Date類(lèi)
public:private:year
SetDate()monthday
IsLeapYear()Protected:
Print()
圖10.2Date類(lèi)的描述例程10.2(p350)用類(lèi)定義一個(gè)計(jì)數(shù)器的抽象數(shù)據(jù)類(lèi)型ADT(AbstractDataType)。計(jì)數(shù)器允許取值范圍為0~4294967295的正整數(shù),可進(jìn)行的操作是計(jì)數(shù)器加1、減1和讀計(jì)數(shù)器的值。其類(lèi)的定義如下:
#include<iostream.h>classCounter{public:Counter()//Counter類(lèi)的構(gòu)造函數(shù)。 {value=0;//初始化數(shù)據(jù)成員值。cout<<"Constructorcalled!\n";//輸出顯示調(diào)用了本構(gòu)造函數(shù)的信息。}
voidIncrement()//在允許取值范圍內(nèi)計(jì)數(shù)器加1。 {if(value<4294967295)value++;} voidDecrement()//當(dāng)計(jì)數(shù)器的數(shù)據(jù)成員值不為0時(shí)減1。 {if(value>0)value--;}unsignedReadValue()//讀計(jì)數(shù)器的值{returnvalue;}~Counter()//Counter類(lèi)的析構(gòu)函數(shù)。{cout<<"Destructorcalled!\n";}//只輸出調(diào)用了本析構(gòu)函數(shù)的信息,其它什么也不做。
private: unsignedvalue;//Counter類(lèi)的私有數(shù)據(jù)成員。};
voidmain()//Counter類(lèi)的測(cè)試程序。{
Counterc1,c2;//定義了Counter類(lèi)的兩個(gè)對(duì)象c1和c2。
for(inti=1;i<=6;i++){ c1.Increment();//在第1個(gè)for語(yǔ)句的循環(huán)體內(nèi)6次向
對(duì)象c1發(fā)送增量運(yùn)算的消息。
cout<<"valueofc1="<<c1.ReadValue()<<endl;//每循環(huán)一次,顯示對(duì)象c1的計(jì)數(shù)值。
c2.Increment();//同樣6次向?qū)ο骳2發(fā)送增量運(yùn)算的消
息。
}
cout<<"Afterloop,valueofc2="<<c2.ReadValue()<<endl;//循環(huán)完成后,顯示對(duì)象c2的計(jì)數(shù)值。
for(i=1;i<=5;i++) c2.Decrement();//在第2個(gè)for語(yǔ)句的循環(huán)體內(nèi)5次向?qū)ο骳2
發(fā)送減量運(yùn)算的消息。cout<<"Finalvalueofc1="<<c1.ReadValue()<<",valueofc2="<<c2.ReadValue()<<endl;}//顯示對(duì)象c1和c2最終的計(jì)數(shù)值。
該程序的輸出結(jié)果:Constructorcalled!Constructorcalled!valueofc1=1valueofc1=2valueofc1=3valueofc1=4valueofc1=5valueofc1=6Afterloop,valueofc2=6Finalvalueofc1=6,valueofc2=1Destructorcalled!Destructorcalled!
3.?dāng)?shù)據(jù)成員:如前所述,類(lèi)的定義與結(jié)構(gòu)體的定義一樣,僅僅定義了類(lèi)的組織形式,給出了一個(gè)新的class類(lèi)型,編譯系統(tǒng)并不給類(lèi)的每個(gè)數(shù)據(jù)成員分配具體的內(nèi)存空間。數(shù)據(jù)成員既可以放在公有部分稱(chēng)為公有數(shù)據(jù)成員,又可以放在私有或保護(hù)部分稱(chēng)為私有或保護(hù)數(shù)據(jù)成員。它們的定義格式都是:
<類(lèi)型>數(shù)據(jù)成員名;(1)數(shù)據(jù)成員只有<類(lèi)型>說(shuō)明,而無(wú)<存儲(chǔ)類(lèi)>說(shuō)明,所以將類(lèi)的數(shù)據(jù)成員說(shuō)明為auto、register和extern型都是無(wú)意義的。
(2)在類(lèi)體中不允許對(duì)所定義的數(shù)據(jù)成員進(jìn)行初始化。例如,下面的定義都是錯(cuò)誤的:classCounter{public:...private: unsignedvalue=0;//error};classDate{public:
...private:
intyear(1999),month(9),day(16);//error};(3)數(shù)據(jù)成員的類(lèi)型可以是基本數(shù)據(jù)類(lèi)型(char、int、...、double等)和復(fù)雜數(shù)據(jù)類(lèi)型(數(shù)組、指針、引用、...、結(jié)構(gòu)變量等),或已經(jīng)定義了的類(lèi)對(duì)象。當(dāng)另一個(gè)類(lèi)的對(duì)象作為這個(gè)類(lèi)的成員時(shí),稱(chēng)為“對(duì)象成員”,這另一個(gè)類(lèi)必須預(yù)先定義好。例如:(教材p352,參見(jiàn)p52exg.cpp)classN{public:
...};//不能采用先聲明,后定義的形式?!眂lassN;”classM{public:
...
private:Nn;//n是N類(lèi)的對(duì)象};
4.成員函數(shù)(MemberFunction):類(lèi)體(即緊跟類(lèi)頭后一對(duì)大括號(hào)所包圍的程序部分)中不僅定義了該類(lèi)的對(duì)象所具有的數(shù)據(jù)結(jié)構(gòu),還定義了對(duì)該類(lèi)對(duì)象進(jìn)行操作的成員函數(shù)(方法),其定義格式如下:
<返回類(lèi)型>[<類(lèi)名>::]成員函數(shù)名函數(shù)頭(類(lèi)型
參數(shù)1,...,類(lèi)型
參數(shù)n){...
...
...}
函數(shù)體(1)所有成員函數(shù)都必須在類(lèi)體內(nèi)用函數(shù)原型加以聲明。而成員函數(shù)的定義(方法的實(shí)現(xiàn)部分)則較靈活,既可在類(lèi)體外定義,也可在類(lèi)體內(nèi)定義。在類(lèi)體外定義成員函數(shù)時(shí),必須用類(lèi)名加作用域運(yùn)算符’::’來(lái)指明所定義的成員函數(shù)屬于哪個(gè)類(lèi);在類(lèi)體內(nèi)定義的成員函數(shù),其函數(shù)頭可不寫(xiě)
[<類(lèi)名>::]。
(2)在類(lèi)體內(nèi)定義成員函數(shù)時(shí),編譯系統(tǒng)自動(dòng)地將成員函數(shù)當(dāng)作內(nèi)聯(lián)函數(shù)處理,其函數(shù)頭前不必寫(xiě)關(guān)鍵字”inline”。例如Counter類(lèi)中的Increment()、Decrement()和
ReadValue()都是內(nèi)聯(lián)函數(shù)。若是類(lèi)體外定義的成員函數(shù),必須用關(guān)鍵字”inline”指明它為內(nèi)聯(lián)函數(shù)。(3)在定義了類(lèi)的對(duì)象后,才可以用如下格式調(diào)用(公有)成員函數(shù):對(duì)象名.成員函數(shù)名(實(shí)參表);例如:
Counterc1,c2;c1.Increment();
c2.Decrement();
(4)成員函數(shù)與普通函數(shù)一樣,可設(shè)置參數(shù)的默認(rèn)值(缺省值Default)。
§11.2對(duì)象的定義:定義一個(gè)類(lèi)就相當(dāng)于創(chuàng)建了一個(gè)新的class類(lèi)型。要使用類(lèi),還必須用已經(jīng)定義的類(lèi)去說(shuō)明它的實(shí)例變量(對(duì)象)。在C++中,class類(lèi)型一旦被定義,它的實(shí)例變量(對(duì)象)就能被創(chuàng)建、初始化、并定義指針變量指向它。在程序中,該類(lèi)名就可以象基本數(shù)據(jù)類(lèi)型‘int’;、...、‘double’等一樣使用,用來(lái)定義具體的實(shí)例變量(對(duì)象)。例如:Datedate1,date2,date[31],*pdate;Counterc1,c2,*pc;
1.對(duì)象的定義格式:在定義好稱(chēng)之為“類(lèi)名”的一個(gè)類(lèi)以后,就可以用如下格式定義它的對(duì)象:<存儲(chǔ)類(lèi)><類(lèi)名><對(duì)象名表>;<對(duì)象名表>中可以有一個(gè)或多個(gè)對(duì)象名,若為多個(gè)對(duì)象名時(shí)用逗號(hào)分隔開(kāi)。對(duì)象名可以是一般對(duì)象名(如上例中Date、Counter為類(lèi)名,date1、date2為Date類(lèi)的兩個(gè)一般對(duì)象名,c1、c2為Counter類(lèi)的一般對(duì)象),也可以是對(duì)象數(shù)組名(如date[31]是由31個(gè)Date類(lèi)的對(duì)象有序排列成date[0]、date[1]、...、date[30]等組成的集合,取對(duì)象數(shù)組名為date),還可以是指向該類(lèi)對(duì)象的指針名或?qū)υ擃?lèi)對(duì)象的引用名。例如:Datedate1,&Rdate=date1;Counterc1,&Rc=c1;
2.指向?qū)ο蟮闹羔槪ê?jiǎn)稱(chēng)“對(duì)象指針”):(1)對(duì)象指針的定義格式:<存儲(chǔ)類(lèi)><類(lèi)名>指針名;例如:Counterc1,c2,*pc;這里所說(shuō)的<存儲(chǔ)類(lèi)>是指針變量本身的存儲(chǔ)類(lèi)型,與ANSIC標(biāo)準(zhǔn)一樣,有extern型、static型、auto型等。而auto的說(shuō)明經(jīng)常缺省,extern在定義時(shí)不寫(xiě),聲明時(shí)必須寫(xiě)。順便指出,例中只定義了一個(gè)對(duì)象指針pc,但pc并沒(méi)有定向,還必須通過(guò)初始化或賦值操作將已存在的對(duì)象地址賦給它。即pc=&c1;另外,在C++中對(duì)象指針可作為另一個(gè)類(lèi)的成員,此時(shí)的對(duì)象指針是沒(méi)有<存儲(chǔ)類(lèi)>說(shuō)明的。
(2)只要一個(gè)類(lèi)已經(jīng)聲明(可以沒(méi)有定義),則指向該類(lèi)的對(duì)象指針或該類(lèi)對(duì)象的引用都可作為另一個(gè)類(lèi)的成員。例如:
#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.訪問(wèn)類(lèi)對(duì)象成員的方法:如前所述,類(lèi)有兩種成員,即數(shù)據(jù)成員和成員函數(shù)。每個(gè)對(duì)象都是類(lèi)的一個(gè)實(shí)例,都具有自己的數(shù)據(jù)成員值,而該類(lèi)所有對(duì)象的數(shù)據(jù)結(jié)構(gòu)及其訪問(wèn)權(quán)限卻是由它的類(lèi)統(tǒng)一定義的。因此同一個(gè)類(lèi)所創(chuàng)建的對(duì)象,其數(shù)據(jù)結(jié)構(gòu)都是相同的,類(lèi)中的成員函數(shù)是共享的,而不同對(duì)象的數(shù)據(jù)成員值可以是不相同的。例如,對(duì)已經(jīng)定義的Counter類(lèi)可用如下語(yǔ)句定義對(duì)象和對(duì)象指針:
Counterc1,c2,*pc;對(duì)象c1、c2都具有各自的value值,但value的數(shù)據(jù)類(lèi)型(unsigned)和訪問(wèn)權(quán)限(private)則由Counter類(lèi)統(tǒng)一定義。由于它是私有數(shù)據(jù)成員,程序的其他部分不能直接訪問(wèn)它,必須通過(guò)公有部分的成員函數(shù)。c1.value;//error不能直接訪問(wèn)私有數(shù)據(jù)成員c1.ReadValue();//用公有成員函數(shù)訪問(wèn)私有數(shù)據(jù)成員
(1)數(shù)據(jù)成員的訪問(wèn)方法:如上所述,對(duì)于私有數(shù)據(jù)成員只能通過(guò)公有成員函數(shù)才能訪問(wèn)它。而公有數(shù)據(jù)成員可直接訪問(wèn)它,其格式為:
對(duì)象名.公有數(shù)據(jù)成員名或
對(duì)象指針名->公有數(shù)據(jù)成員名其中<對(duì)象指針名>應(yīng)與對(duì)象屬于相同的class類(lèi)型,且必須通過(guò)初始化或賦值操作將已存在的對(duì)象地址賦給它。當(dāng)然也可以通過(guò)成員函數(shù)訪問(wèn)它。Point類(lèi)的定義寫(xiě)成如下程序代碼,并把它存放在tpoint.h的頭文件中:
(P358)classPoint{public://四個(gè)公有成員函數(shù)。
voidSetPoint(inta,intb);//設(shè)定點(diǎn)的X、Y坐標(biāo)值。int
ReadX(){returnx;}//讀取點(diǎn)的X坐標(biāo)值。int
ReadY(){returny;}//讀取點(diǎn)的Y坐標(biāo)值。voidMove(int
xOffset,
int
yOffset);//計(jì)算點(diǎn)移動(dòng)后的X、Y坐標(biāo)值。
intx,y;//兩個(gè)公有數(shù)據(jù)成員x和y。};voidPoint::SetPoint(inta,intb){x=a;y=b;}voidPoint::Move(int
xOffset,
int
yOffset){x+=xOffset;y+=yOffset;}例11.5編寫(xiě)Point類(lèi)的測(cè)試程序。#include<iostream.h>#include"tpoint.h"voidmain(){Pointp1,p2;//定義Point類(lèi)的兩個(gè)對(duì)象p1和p2。Point&ref=p1,*ptr=&p2;//還定義了一個(gè)對(duì)對(duì)象p1的引用ref和指向?qū)ο髉2的對(duì)象指針ptr。 p1.x=3;p1.y=5;
//可用對(duì)象名直接訪問(wèn)公有數(shù)據(jù)成員,給p1
點(diǎn)設(shè)定X、Y坐標(biāo)值。
p2.SetPoint(8,10);//也可用公有成員函數(shù)SetPoint()給p1點(diǎn)設(shè)定X、Y坐標(biāo)值。
p1.Move(2,1);//調(diào)用公有成員函數(shù)Move(),移動(dòng)p1點(diǎn)。
p2.Move(1,-2);//調(diào)用公有成員函數(shù)Move(),移動(dòng)p2點(diǎn)。
cout<<"x1="<<ref.x<<","<<"y1="<<ref.y<<endl;//使用對(duì)象引用ref代替p1直接訪問(wèn)它的公有數(shù)據(jù)成員x和y。
cout<<"x2="<<ptr->x<<","<<"y2="<<ptr->y<<endl;//使用對(duì)象指針ptr代替p2直接訪問(wèn)它的公有數(shù)據(jù)成員x和y。}
該程序的輸出結(jié)果:x1=5,y1=6x2=9,y2=8(2)成員函數(shù)的訪問(wèn)方法:訪問(wèn)成員函數(shù)的格式:
對(duì)象名.公有成員函數(shù)名(參數(shù)表);
或
對(duì)象指針名->公有成員函數(shù)名(參數(shù)表);
其中<對(duì)象指針名>應(yīng)與對(duì)象屬于相同的class類(lèi)型,且必須通過(guò)定向操作指向了已存在的對(duì)象。(3)通過(guò)引用對(duì)象訪問(wèn)成員的方法。引用對(duì)象可用來(lái)代替被引用的對(duì)象名訪問(wèn)成員,其格式:
引用對(duì)象名.公有數(shù)據(jù)成員名或
引用對(duì)象名.公有成員函數(shù)名(參數(shù)表)§10.3對(duì)象的初始化:構(gòu)造函數(shù)和析構(gòu)函數(shù)是在類(lèi)體中說(shuō)明的兩種特殊的成員函數(shù)。1.構(gòu)造函數(shù):C++中“類(lèi)”只定義了一組對(duì)象的類(lèi)型。要使用這個(gè)類(lèi)還必須用“類(lèi)”說(shuō)明它的對(duì)象,每個(gè)對(duì)象中的數(shù)據(jù)成員還必須賦初值,這些功能都是由構(gòu)造函數(shù)完成的。(1)構(gòu)造函數(shù)是一種特殊的成員函數(shù),其定義格式和其他成員函數(shù)相同,只是它以類(lèi)名作為函數(shù)名,例如Counter類(lèi)的構(gòu)造函數(shù)為Counter(),且不能指定返回類(lèi)型和顯式的返回值,連void都不能寫(xiě),即無(wú)返回類(lèi)型。若某類(lèi)定義了構(gòu)造函數(shù),則每當(dāng)該類(lèi)的對(duì)象創(chuàng)建時(shí),編譯系統(tǒng)為它的對(duì)象分配內(nèi)存空間,并自動(dòng)調(diào)用構(gòu)造函數(shù)初始化所創(chuàng)建的對(duì)象,從而確保每個(gè)對(duì)象自動(dòng)地初始化。例如:
Counterc1;編譯系統(tǒng)為對(duì)象c1的每個(gè)數(shù)據(jù)成員(value)分配內(nèi)存空間,并調(diào)用構(gòu)造函數(shù)Counter()自動(dòng)地初始化對(duì)象c1的value值設(shè)置為0。(2)構(gòu)造函數(shù)只完成新對(duì)象的初始化工作,不執(zhí)行對(duì)象的主要任務(wù)。即在類(lèi)創(chuàng)建新對(duì)象時(shí),為對(duì)象分配內(nèi)存空間,給數(shù)據(jù)成員賦初值。(3)幾乎每個(gè)類(lèi)都定義了多個(gè)構(gòu)造函數(shù),以適應(yīng)創(chuàng)建對(duì)象時(shí),對(duì)象的參數(shù)具有不同個(gè)數(shù)的情況,即構(gòu)造函數(shù)可重載。P360,例10.6#include<iostream.h>classComplex{public:Complex(doublereal,doubleimag);//Constructor(1),一般構(gòu)造函數(shù)。
Complex(void);//Constructor(2),無(wú)參數(shù)構(gòu)造函數(shù)。
Complex(constComplex&c); //Constructor(3),復(fù)制構(gòu)造函數(shù)
Complex(doublereal);//Constructor(4),類(lèi)型轉(zhuǎn)換構(gòu)造函數(shù)。
voidprint(inti);private:doublereal,imag;};//一般構(gòu)造函數(shù),用兩個(gè)實(shí)數(shù)分別給新創(chuàng)建對(duì)象的
兩個(gè)數(shù)據(jù)成員賦初值。
Complex::Complex(doubler,doublei){real=r;imag=i;
cout<<"Constructor(1)called:real="<<real<<",imag="<<imag<<endl;//輸出被調(diào)用的提示信息。}//無(wú)參數(shù)構(gòu)造函數(shù),創(chuàng)建新對(duì)象并將它的數(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ù),把已存在對(duì)象的每個(gè)數(shù)據(jù)成員
都對(duì)應(yīng)賦值給新創(chuàng)建對(duì)象的數(shù)據(jù)成員,即對(duì)新
創(chuàng)建對(duì)象進(jìn)行“位模式拷貝”。*/Complex::Complex(constComplex&c){real=c.real;imag=c.imag;
cout<<"Constructor(3)called:real="<<real<<",imag="<<imag<<endl;//輸出被調(diào)用的提示信息。}//類(lèi)型轉(zhuǎn)換構(gòu)造函數(shù),把一個(gè)實(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ù)類(lèi)對(duì)象的值,形參i用來(lái)表示對(duì)
象的序號(hào)。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ù)類(lèi)對(duì)象c1。c2.print(2);//輸出顯示復(fù)數(shù)類(lèi)對(duì)象c2。
c3.print(3);//輸出顯示復(fù)數(shù)類(lèi)對(duì)象c3。c4.print(4);//輸出顯示復(fù)數(shù)類(lèi)對(duì)象c4。c1=Complex(1.2,3.4);//直接調(diào)用構(gòu)造函數(shù)。
c3=c2;//把復(fù)數(shù)類(lèi)對(duì)象c2的每個(gè)數(shù)據(jù)成員值賦給c3。
c2=5;//調(diào)用類(lèi)型轉(zhuǎn)換構(gòu)造函數(shù),把實(shí)數(shù)轉(zhuǎn)換成復(fù)數(shù)。
c1.print(1);//輸出顯示復(fù)數(shù)類(lèi)對(duì)象c1。
c2.print(2);//輸出顯示復(fù)數(shù)類(lèi)對(duì)象c2。c3.print(3);//輸出顯示復(fù)數(shù)類(lèi)對(duì)象c3。c4.print(4);//輸出顯示復(fù)數(shù)類(lèi)對(duì)象c4。}
該程序輸出結(jié)果:
Constructor(2)called:real=0,imag=0//創(chuàng)建c1,調(diào)用無(wú)參數(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);”語(yǔ)句。c2=6+8i//執(zhí)行“c2.print(2);”語(yǔ)句。
c3=5.6+7.9i//執(zhí)行“c3.print(3);”語(yǔ)句。
c4=6+8i//執(zhí)行“c4.print(4);”語(yǔ)句。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)建對(duì)象時(shí)顯式地調(diào)用構(gòu)造函數(shù)。(p266)例如,
Datetoday=Date(1998,4,9);Counterc1=Counter();將today定義為類(lèi)Date的對(duì)象,并調(diào)用構(gòu)造函數(shù)Date(inty,intm,intday);初始化對(duì)象today的數(shù)據(jù)成員year,month,day。其格式為:
類(lèi)名
對(duì)象名=構(gòu)造函數(shù)名(實(shí)參表);
由于“構(gòu)造函數(shù)名”就是“類(lèi)名”,所以可用更簡(jiǎn)單的形式:
類(lèi)名
對(duì)象名(實(shí)參表);此時(shí)是在創(chuàng)建對(duì)象時(shí),隱式地(自動(dòng)地)調(diào)用構(gòu)造函數(shù)。
2.析構(gòu)函數(shù):它是構(gòu)造函數(shù)的配對(duì)物,與構(gòu)造函數(shù)一樣是與類(lèi)同名的成員函數(shù),并在函數(shù)名前加上一個(gè)’~’以便與構(gòu)造函數(shù)相區(qū)別。例如:count.cpp中的析構(gòu)函數(shù)~Counter()。
(1)一個(gè)類(lèi)只能有一個(gè)析構(gòu)函數(shù),且析構(gòu)函數(shù)沒(méi)有參數(shù)和返回值,它實(shí)現(xiàn)與構(gòu)造函數(shù)相反的功能。在刪除對(duì)象時(shí)執(zhí)行一些清理任務(wù),例如釋放對(duì)象所占用的內(nèi)存空間,有些對(duì)象可能還需做其他的事情,如當(dāng)撤消一個(gè)顯示窗口對(duì)象時(shí),還需將它們從屏幕上清除掉。(2)對(duì)于用new創(chuàng)建的(動(dòng)態(tài))對(duì)象,只有用delete撤消時(shí)編譯系統(tǒng)才調(diào)用析構(gòu)函數(shù)。
(3)如果編程者沒(méi)有給類(lèi)定義析構(gòu)函數(shù),那么編譯系統(tǒng)將生成一個(gè)什么也不做的缺省析構(gòu)函數(shù)。例如,Complex類(lèi)的缺省析構(gòu)函數(shù)為:
Complex::~Complex(){}//空函數(shù)有人會(huì)問(wèn)為什么要把缺省析構(gòu)函數(shù)設(shè)計(jì)成什么都不做(對(duì)編程者來(lái)說(shuō))呢?因?yàn)橹挥羞@樣對(duì)于各種存儲(chǔ)類(lèi)的對(duì)象,才能夠按照它本來(lái)的創(chuàng)建和撤消管理機(jī)制運(yùn)行。例如,自動(dòng)對(duì)象在程序運(yùn)行期間,每當(dāng)遇到它的聲明時(shí)就創(chuàng)建它,當(dāng)離開(kāi)它的作用域時(shí)就自動(dòng)撤消它。這將在§10.6對(duì)象的存儲(chǔ)類(lèi)中詳細(xì)講述。
(4)編譯系統(tǒng)自動(dòng)調(diào)用構(gòu)造函數(shù)的次序和調(diào)用析構(gòu)函數(shù)的次序是相反的。為了驗(yàn)證這一點(diǎn),給Counter類(lèi)新增加一個(gè)私有數(shù)據(jù)成員intwho;用來(lái)記錄所生成對(duì)象的序號(hào),變?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ù)的種類(lèi):構(gòu)造函數(shù)可帶有各種類(lèi)型的參數(shù),根據(jù)參數(shù)所具有的類(lèi)型可將它分為如下四種:(1)無(wú)參數(shù)的構(gòu)造函數(shù):當(dāng)程序中寫(xiě)有這樣的語(yǔ)句定義新對(duì)象時(shí),如:voidmain(){Complexc1;...}則在Complex類(lèi)中必須定義這樣一個(gè)構(gòu)造函數(shù),Complex::Complex(void){r
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 初一的數(shù)學(xué)題目及答案
- 初三化學(xué)期末考試試卷及答案
- 初級(jí)經(jīng)濟(jì)師試題及答案
- 2026春人教鄂教版(2024)小學(xué)科學(xué)一年級(jí)下冊(cè)《多彩的花》課時(shí)練習(xí)及答案
- 2025秋冀教版(三起)小學(xué)英語(yǔ)六年級(jí)上冊(cè)知識(shí)點(diǎn)及期末測(cè)試卷及答案
- 2026年水電暖工程師面試題及答案
- 2026年銀行柜員崗位常見(jiàn)問(wèn)題及答案解析
- 2026年質(zhì)量認(rèn)證管理員崗位面試題庫(kù)含答案
- 首付延期付款協(xié)議書(shū)
- 2026年高考乙卷物理真題試卷及答案
- 華能邯峰電廠2025年下半年度應(yīng)屆高校畢業(yè)生招聘易考易錯(cuò)模擬試題(共500題)試卷后附參考答案
- 礦山企業(yè)年終總結(jié)與反思
- 學(xué)業(yè)水平考務(wù)培訓(xùn)
- 2025年新護(hù)士各層級(jí)的崗位職責(zé)試題(附答案)
- 2026年黑龍江農(nóng)墾職業(yè)學(xué)院?jiǎn)握新殬I(yè)適應(yīng)性測(cè)試必刷測(cè)試卷新版
- 2026江蘇春季高考語(yǔ)文學(xué)業(yè)考試總復(fù)習(xí):專(zhuān)題07 語(yǔ)言表達(dá)得體(原卷版)
- 運(yùn)城十三縣考試題及答案
- 【書(shū)法練習(xí)】中考語(yǔ)文古詩(shī)文硬筆字帖(田英章字體)
- 貴州省市政工程計(jì)價(jià)定額2025定額說(shuō)明(重要)
- 車(chē)輛日常保養(yǎng)與維護(hù)課件
- 農(nóng)村集體經(jīng)濟(jì)發(fā)展講座
評(píng)論
0/150
提交評(píng)論