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

下載本文檔

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

文檔簡介

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

對象生滅

Chapter9

ObjectBirth&Death

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

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

Dateg;//去掉括號對以下形式的正確理解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ù)中通用的校驗工作的代碼分離出來,單獨成為一個成員函數(shù)并供所有版本的構(gòu)造函數(shù)調(diào)用。舉例f09049.2.2無參構(gòu)造函數(shù)對象創(chuàng)建必須而且只能通過構(gòu)造函數(shù)前面第8章的程序沒有任何錯誤的原因:默認的無參構(gòu)造函數(shù)2/5/202399.2構(gòu)造函數(shù)的重載9.2.2無參構(gòu)造函數(shù)

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

Date(inty,intm,intd);

//...};intmain(){Dated;//error}2/5/2023109.3類成員初始化9.3.1默認調(diào)用的無參構(gòu)造函數(shù)類成員的概念:類中的某個數(shù)據(jù)成員是另外一個類的對象類成員初始化時的簡單處理方法及其執(zhí)行過程的分析f0905如果不加特殊處理,則肯定調(diào)用類成員的無參構(gòu)造函數(shù)9.3.2初始化的困惑一種企圖及其初始化目的的破滅f0906常量成員和引用成員初始化時也存在一種特殊性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成員初始化的正確形式冒號語法:在構(gòu)造函數(shù)的形參列表的右括號外、花括號前面,使用冒號語法引出構(gòu)造函數(shù)的調(diào)用列表程序舉例:f0907冒號語法在初始化成員時可以不出現(xiàn)類的類型聲明,這是一種破例PPointd(3,2);Cout<<d(6,8);//errorCout<<d.angle();常量成員、引用成員甚至是普通數(shù)據(jù)成員也可以通過冒號語法進行初始化2/5/2023139.4構(gòu)造順序9.4.1局部對象(含自動和靜態(tài))對象或變量創(chuàng)建的語句行順序與運行順序inta=3;if(a==2)Dated;Datee;

則對象創(chuàng)建的語句行順序為:

Dated--->Datee

對象創(chuàng)建的運行順序為:

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

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

classStudent{public:

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

intmain(){stringt=“jenny”;

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

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

fn(“Jenny”)不能匹配

voidfn(constStudent&s);

因為:”Jenny”->string->Student

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

Persond,g;

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

Person&operator=(constPerson&p){

memcpy(this,&p,sizeof(p));}默認的賦值運算符在對象本體和對象實體不一致時將會產(chǎ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;}};定義賦值操作符:排除客體對象與本對象同一的情況釋放本對象的資源申請客體對象相同大小的資源空間拷貝客體對象的資源到本對象9.7轉(zhuǎn)型與賦值2/5/202326賦值運算符的重載和復(fù)制構(gòu)造函數(shù)是完全不同的概念,其功能也是完全不同的賦值運算符和復(fù)制構(gòu)造函數(shù)不同的調(diào)用場合舉例:DATEObj1=Obj2;DATEObj1(Obj2);DATEObj1,Obj2;Obj1=Obj2;voidfun(DATE

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

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論