C++程序設(shè)計(jì)教程9_第1頁(yè)
C++程序設(shè)計(jì)教程9_第2頁(yè)
C++程序設(shè)計(jì)教程9_第3頁(yè)
C++程序設(shè)計(jì)教程9_第4頁(yè)
C++程序設(shè)計(jì)教程9_第5頁(yè)
已閱讀5頁(yè),還剩23頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

C++程序設(shè)計(jì)教程(第二版)第九章

對(duì)象生滅

Chapter9

ObjectBirth&Death

蘇州大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院2/5/20231第九章內(nèi)容構(gòu)造函數(shù)設(shè)計(jì)(ConstructorDesign)

構(gòu)造函數(shù)重載(ConstructorOverload)

類成員初始化(ClassMemberInitializations)

構(gòu)造順序(ConstructingOrder)拷貝構(gòu)造函數(shù)(CopyConstructors)

析構(gòu)函數(shù)(Destructors)

轉(zhuǎn)型與賦值(Conversion&Assignment)2/5/202329.1構(gòu)造函數(shù)設(shè)計(jì)9.1.1初始化要求變量的初始化:雖然在定義的同時(shí)并不一定需要進(jìn)行初始化,但無(wú)論如何在參加后續(xù)計(jì)算前必須先要給定初值intmonth;intmonth=1;對(duì)象與變量的不同在于對(duì)象對(duì)應(yīng)于事物,要求從誕生之時(shí)起便有明確的意義.對(duì)象若無(wú)初始化,將發(fā)生以下情況:全部對(duì)象:全0位的模式局部對(duì)象:隨機(jī)值舉例:f0901對(duì)象必須建立一種初始化機(jī)制,以滿足針對(duì)不同條件下的賦初值操作的要求2/5/202339.1構(gòu)造函數(shù)設(shè)計(jì)9.1.2封裝性要求結(jié)構(gòu)體變量初始化時(shí)的公有成員特性structPoint;Pointd={2,3};Pointd;d.x=2;d.y=3;//OK!!!C++中的類具有封裝的特性classPoint;Pointd={2,3};//錯(cuò)誤!!!對(duì)象創(chuàng)建過(guò)程中的特殊性:數(shù)據(jù)成員一般是私有的;傳遞的不僅僅是一個(gè)簡(jiǎn)單的值,可能是一種信息;初始化的過(guò)程中除了計(jì)算操作以外,還需要進(jìn)行必要的驗(yàn)證工作;封裝性要求對(duì)象創(chuàng)建過(guò)程中按傳遞的信息進(jìn)行一個(gè)過(guò)程化的初始化工作2/5/202349.1構(gòu)造函數(shù)設(shè)計(jì)9.1.3函數(shù)形式初始化的操作應(yīng)該是一個(gè)過(guò)程,必須由函數(shù)才能完成;構(gòu)造函數(shù):類定義中專門用于完成對(duì)象創(chuàng)建和初始化的特殊成員函數(shù)構(gòu)造函數(shù)的命名應(yīng)該是唯一的;調(diào)用構(gòu)造函數(shù)必須用對(duì)象名進(jìn)行激活,但使用對(duì)象名作為構(gòu)造函數(shù)是不現(xiàn)實(shí)的;使用類名成為最佳選擇;舉例2/5/202359.1構(gòu)造函數(shù)設(shè)計(jì)9.1.4構(gòu)造函數(shù)的返回值問(wèn)題變量創(chuàng)建失敗的后果及其處理方法對(duì)象創(chuàng)建失敗后的處理方法:程序捕捉異常直接終止程序的執(zhí)行構(gòu)造函數(shù)不應(yīng)該有表示任何意義的返回值構(gòu)造函數(shù)也不是空類型(void)的函數(shù)構(gòu)造函數(shù)中禁止出現(xiàn)return語(yǔ)句9.1.5set的缺憾及其改進(jìn)兩種模式的對(duì)比Dated(2005,12,28);Dated;d.set(2005,12,28);改進(jìn)后的程序舉例f09022/5/202369.1構(gòu)造函數(shù)設(shè)計(jì)9.1.6一次性對(duì)象在創(chuàng)建對(duì)象時(shí)不給出對(duì)象名,而直接以類名調(diào)用構(gòu)造函數(shù),則將產(chǎn)生一個(gè)無(wú)名的一次性對(duì)象舉例cout<<Date(2003,12,23);使用場(chǎng)合:一般用在創(chuàng)建后不需要反復(fù)使用的場(chǎng)合(如參數(shù)傳遞時(shí))2/5/202379.2構(gòu)造函數(shù)的重載9.2.1重載構(gòu)造函數(shù)

構(gòu)造函數(shù)可以重載,也可以參數(shù)默認(rèn)程序舉例:f0903無(wú)參構(gòu)造函數(shù)調(diào)用時(shí)的特殊形式Dateg();形式上的歧義,和函數(shù)聲明混淆為了加以區(qū)分,C++語(yǔ)法體系規(guī)定采用以下形式:

Dateg;//去掉括號(hào)對(duì)以下形式的正確理解inta;intb();Dateg;Datef();有參構(gòu)造函數(shù)調(diào)用和函數(shù)聲明在形式上的比較Datee(2002);Datee(inty);2/5/202389.2構(gòu)造函數(shù)的重載9.2.1重載構(gòu)造函數(shù)

在構(gòu)造函數(shù)重載中,可以將各構(gòu)造函數(shù)中通用的校驗(yàn)工作的代碼分離出來(lái),單獨(dú)成為一個(gè)成員函數(shù)并供所有版本的構(gòu)造函數(shù)調(diào)用。舉例f09049.2.2無(wú)參構(gòu)造函數(shù)對(duì)象創(chuàng)建必須而且只能通過(guò)構(gòu)造函數(shù)前面第8章的程序沒(méi)有任何錯(cuò)誤的原因:默認(rèn)的無(wú)參構(gòu)造函數(shù)2/5/202399.2構(gòu)造函數(shù)的重載9.2.2無(wú)參構(gòu)造函數(shù)

默認(rèn)的無(wú)參構(gòu)造函數(shù)的使用規(guī)則:若某類未定義任何一個(gè)構(gòu)造函數(shù),則系統(tǒng)將提供一個(gè)默認(rèn)的無(wú)參構(gòu)造函數(shù)無(wú)參構(gòu)造函數(shù)僅能完成對(duì)象空間的申請(qǐng)工作,不能完成其它任何的初始化工作若某類定義樂(lè)任何一個(gè)構(gòu)造函數(shù),則系統(tǒng)將不再提供默認(rèn)的無(wú)參構(gòu)造函數(shù);若此時(shí)仍然需要,則需用戶自己定義classDate{public:

Date(inty,intm,intd);

//...};intmain(){Dated;//error}2/5/2023109.3類成員初始化9.3.1默認(rèn)調(diào)用的無(wú)參構(gòu)造函數(shù)類成員的概念:類中的某個(gè)數(shù)據(jù)成員是另外一個(gè)類的對(duì)象類成員初始化時(shí)的簡(jiǎn)單處理方法及其執(zhí)行過(guò)程的分析f0905如果不加特殊處理,則肯定調(diào)用類成員的無(wú)參構(gòu)造函數(shù)9.3.2初始化的困惑一種企圖及其初始化目的的破滅f0906常量成員和引用成員初始化時(shí)也存在一種特殊性2/5/2023119.3類成員初始化9.3.2初始化的困惑classSilly{constintten;int&ra;public:

Silly(intx,int&a){ ten=10;

ra=a;}};2/5/2023129.3類成員初始化9.3.3成員初始化的正確形式冒號(hào)語(yǔ)法:在構(gòu)造函數(shù)的形參列表的右括號(hào)外、花括號(hào)前面,使用冒號(hào)語(yǔ)法引出構(gòu)造函數(shù)的調(diào)用列表程序舉例:f0907冒號(hào)語(yǔ)法在初始化成員時(shí)可以不出現(xiàn)類的類型聲明,這是一種破例PPointd(3,2);Cout<<d(6,8);//errorCout<<d.angle();常量成員、引用成員甚至是普通數(shù)據(jù)成員也可以通過(guò)冒號(hào)語(yǔ)法進(jìn)行初始化2/5/2023139.4構(gòu)造順序9.4.1局部對(duì)象(含自動(dòng)和靜態(tài))對(duì)象或變量創(chuàng)建的語(yǔ)句行順序與運(yùn)行順序inta=3;if(a==2)Dated;Datee;

則對(duì)象創(chuàng)建的語(yǔ)句行順序?yàn)椋?/p>

Dated--->Datee

對(duì)象創(chuàng)建的運(yùn)行順序?yàn)椋?/p>

Datee在C語(yǔ)言中,局部變量的創(chuàng)建是在函數(shù)開始執(zhí)行時(shí)統(tǒng)一創(chuàng)建的,創(chuàng)建的順序?yàn)樽兞康恼Z(yǔ)句行順序;而C++中,局部對(duì)象的創(chuàng)建是在運(yùn)行時(shí)決定的,而且靜態(tài)對(duì)象只執(zhí)行一次程序舉例:f09082/5/2023149.4.2全局對(duì)象全局對(duì)象在main函數(shù)啟動(dòng)之前生成,而調(diào)試則在main函數(shù)啟動(dòng)之后.上述現(xiàn)象的對(duì)策:調(diào)試時(shí),應(yīng)先將全局對(duì)象作為局部對(duì)象來(lái)運(yùn)行觀察.或者,在構(gòu)造函數(shù)中添加輸出語(yǔ)句來(lái)觀察運(yùn)行過(guò)程.同一工程不同代碼文件全局對(duì)象的創(chuàng)建沒(méi)有明確順序規(guī)定.程序舉例:f0909對(duì)策:不要讓不同文件的全局對(duì)象互為依賴.因?yàn)橐蕾嚲哂邢群笮?,而其全局?duì)象的創(chuàng)建不能保證該依賴性發(fā)揮作用.最好不要使用全局對(duì)象9.4構(gòu)造順序2/5/2023159.4.3成員對(duì)象成員對(duì)象的構(gòu)造順序按類定義中各成員對(duì)象的出現(xiàn)順序來(lái)決定,最后執(zhí)行自身構(gòu)造函數(shù)程序舉例:f09109.4.4構(gòu)造位置全局對(duì)象、常對(duì)象、靜態(tài)對(duì)象放在全局?jǐn)?shù)據(jù)區(qū)局部對(duì)象放在棧區(qū)用戶申請(qǐng)的對(duì)象放在堆區(qū)9.4構(gòu)造順序2/5/2023169.5拷貝構(gòu)造函數(shù)9.5.1對(duì)象本體與對(duì)象實(shí)體對(duì)象本體也是對(duì)象主體;對(duì)象實(shí)體則還包括屬于對(duì)象的衍生物。如:某個(gè)人體是人類對(duì)象的主體,然而某人還擁有父母,房產(chǎn)等屬于某人的世系或資產(chǎn),描述人的屬性不僅僅只是人體數(shù)據(jù).從程序中具體而言,對(duì)象除了包括一般的數(shù)據(jù)成員,還包括指向數(shù)據(jù)的指針.更進(jìn)一步說(shuō):在類中包含指針形式的成員變量時(shí),一般在對(duì)象創(chuàng)建時(shí)還會(huì)申請(qǐng)內(nèi)存空間等形式的資源,從而使得對(duì)象實(shí)體大于對(duì)象本體析構(gòu)函數(shù)的必要性:釋放創(chuàng)建時(shí)申請(qǐng)的空間程序舉例:f09112/5/2023179.5拷貝構(gòu)造函數(shù)9.5.2默認(rèn)拷貝構(gòu)造函數(shù)類的對(duì)象也應(yīng)該能夠和普通變量一樣進(jìn)行同類對(duì)象之間的初始化;若某類中未自定義拷貝構(gòu)造函數(shù),則系統(tǒng)將提供一個(gè)默認(rèn)的拷貝構(gòu)造函數(shù);默認(rèn)拷貝構(gòu)造函數(shù)的功能非常弱:僅能完成新老對(duì)象基于位模式的復(fù)制程序舉例:f0912淺拷貝和深拷貝2/5/2023189.5拷貝構(gòu)造函數(shù)9.5.3自定義拷貝構(gòu)造函數(shù)在對(duì)象本體和實(shí)體不一致時(shí),必須要通過(guò)正確的自定義拷貝構(gòu)造函數(shù)來(lái)避免淺拷貝問(wèn)題程序舉例:f0913自定義拷貝構(gòu)造函數(shù)的形式參數(shù)的理解必須是類對(duì)象的常量引用;引用的目的是為了避免對(duì)象復(fù)制過(guò)程中的死循環(huán);常量限定的目的是為了保護(hù)實(shí)參對(duì)象;而且很多時(shí)候傳遞給構(gòu)造函數(shù)的實(shí)參本身就是const對(duì)象自定義拷貝構(gòu)造函數(shù)被調(diào)用的必要條件:Dateobj1=obj2;Dateobj1(obj2);函數(shù)參數(shù)匹配時(shí)函數(shù)的形參為類的對(duì)象時(shí)為什么需要使用引用形式的原因分析2/5/2023199.5拷貝構(gòu)造函數(shù)9.5.3自定義拷貝構(gòu)造函數(shù)拷貝構(gòu)造函數(shù)并不是必須的,只有當(dāng)對(duì)象本體和對(duì)象實(shí)體不一致時(shí)才是必須的。更明確地說(shuō),只有當(dāng)對(duì)象中含有指針形式的成員變量并占用內(nèi)存資源的時(shí)候才需要。而且必須需要,否則淺拷貝而死機(jī)2/5/2023209.6析構(gòu)函數(shù)對(duì)象結(jié)束其生命時(shí),會(huì)被系統(tǒng)悄悄地銷毀(析構(gòu)).即對(duì)象本體空間與名字脫離關(guān)系.對(duì)象結(jié)束生命時(shí),若對(duì)象本體與對(duì)象實(shí)體不同,則需要人為地進(jìn)行資源釋放,以保證對(duì)象本體失效之前,資源被收回.定義析構(gòu)函數(shù)的目的:

由于對(duì)象本體與實(shí)體不同,所以要進(jìn)行對(duì)象占有資源的釋放工作.一般來(lái)說(shuō):一個(gè)類,若有人為定義的拷貝構(gòu)造函數(shù),則也應(yīng)該定義析構(gòu)函數(shù).因?yàn)閷?duì)象創(chuàng)建中有資源要獲得分配,則對(duì)象失效前必應(yīng)先釋放資源.析構(gòu)函數(shù)的一般語(yǔ)法形式:~類名();析構(gòu)函數(shù)是在對(duì)象生命周期結(jié)束時(shí)自動(dòng)調(diào)用的2/5/2023219.6析構(gòu)函數(shù)析構(gòu)函數(shù)的說(shuō)明:析構(gòu)函數(shù)無(wú)參數(shù)析構(gòu)函數(shù)無(wú)返回值析構(gòu)函數(shù)不能重載析構(gòu)函數(shù)的執(zhí)行順序和構(gòu)造函數(shù)相反程序舉例:f09142/5/2023229.7轉(zhuǎn)型與賦值對(duì)象轉(zhuǎn)型一個(gè)構(gòu)造函數(shù),含有一個(gè)其他數(shù)據(jù)類型的參數(shù),顯然其意義為,用該參數(shù)類型的值可以創(chuàng)建本對(duì)象.從另一方面看,參數(shù)類型的值可以轉(zhuǎn)換為本對(duì)象.

classStudent{public:

Student(conststring&n);//...};voidfn(Student&s);

intmain(){stringt=“jenny”;

fn(t);//參數(shù)為string,卻能匹配Student類型

}2/5/202323對(duì)象轉(zhuǎn)型的規(guī)則:只會(huì)嘗試含有一個(gè)參數(shù)的構(gòu)造函數(shù)如果有二義性,則會(huì)放棄嘗試推導(dǎo)是一次性的,不允許多步推導(dǎo)

fn(“Jenny”)不能匹配

voidfn(constStudent&s);

因?yàn)椋骸盝enny”->string->Student

經(jīng)歷了兩步.9.7轉(zhuǎn)型與賦值2/5/2023249.7.2對(duì)象賦值對(duì)象賦值即對(duì)象拷貝:兩個(gè)已經(jīng)存在的對(duì)象之間的復(fù)制

Persond,g;

d=g;//對(duì)象賦值對(duì)象賦值便是使用類中的賦值操作符.如果類中沒(méi)有定義賦值操作符,則系統(tǒng)悄悄地定義一個(gè)默認(rèn)的賦值操作符:

Person&operator=(constPerson&p){

memcpy(this,&p,sizeof(p));}默認(rèn)的賦值運(yùn)算符在對(duì)象本體和對(duì)象實(shí)體不一致時(shí)將會(huì)產(chǎn)生淺拷貝問(wèn)題如對(duì)象本體和實(shí)體不一致時(shí),必須要自定義賦值運(yùn)算符9.7轉(zhuǎn)型與賦值2/5/202325classPerson{char*pName;public:

Person(char*pN="noName");

Person(constPerson&s);

Person&operator=(constPerson&s){

if(this==&s)returns;delete[]pName;

pName=newchar[strlen(s.pName)+1];

if(pName)strcpy(pName,s.pName);return*this;}~Person(){delete[]pName;}};定義賦值操作符:排除客體對(duì)象與本對(duì)象同一的情況釋放本對(duì)象的資源申請(qǐng)客體對(duì)象相同大小的資源空間拷貝客體對(duì)象的資源到本對(duì)象9.7轉(zhuǎn)型與賦值2/5/202326賦值運(yùn)算符的重載和復(fù)制構(gòu)造函數(shù)是完全不同的概念,其功能也是完全不同的賦值運(yùn)算符和復(fù)制構(gòu)造函數(shù)不同的調(diào)用場(chǎng)合舉例:DATEObj1=Obj2;DATEObj1(Obj2);DATEObj1,Obj2;Obj1=Obj2;voidfun(DATE

Obj);DATEObj1;fun(obj1);voidfun(DATE&Obj);

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 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ì)用戶上傳內(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)論