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

下載本文檔

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

文檔簡介

1、C+程序設(shè)計(jì)(三)常寶寶北京大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系內(nèi)容提要對(duì)象的生命周期構(gòu)造函數(shù)析構(gòu)函數(shù)拷貝構(gòu)造函數(shù)對(duì)象的生命周期在面向?qū)ο蟮某绦蛟O(shè)計(jì)環(huán)境中,整型、實(shí)型以及其它其他基本數(shù)據(jù)類型的變量均可以被視作為特殊對(duì)象。和C語言中變量的類型一樣,C+中對(duì)象可分作三類。n全局對(duì)象w存在于全局?jǐn)?shù)據(jù)區(qū),編譯程序負(fù)責(zé)為其分配存儲(chǔ)空間和回收空間。主函數(shù)運(yùn)行前,其存儲(chǔ)分配及初始化工作已經(jīng)完成,主函數(shù)運(yùn)行結(jié)束后,其所占存儲(chǔ)空間才被回收。n局部對(duì)象w存在于棧區(qū),編譯程序負(fù)責(zé)為其分配存儲(chǔ)空間和回收空間,程序運(yùn)行進(jìn)入其作用域后為其分配存儲(chǔ)空間,在離開其作用域時(shí),其所占空間被回收。n動(dòng)態(tài)分配的對(duì)象w存在于堆區(qū),程序員在需要時(shí)為其

2、分配存儲(chǔ)空間并在不需要時(shí)回收其所占用的存儲(chǔ)空間。對(duì)象的生命周期TDate gd; /定義全局對(duì)象int main() TDate ld; /定義局部對(duì)象 TDate *pd, *pd2; . pd = new TDate;/建立動(dòng)態(tài)分配的對(duì)象 . delete pd;/動(dòng)態(tài)分配對(duì)象所占空間被回收 pd2 = func(); delete pd2;/局部對(duì)象所占空間被回收/程序運(yùn)行結(jié)束時(shí),全局對(duì)象所占據(jù)空間被回收TDate* func() TDate ld1; TDate *pd1; . pd1 = new TDate; . return pd1;/動(dòng)態(tài)對(duì)象未回收 對(duì)象的生命周期對(duì)象從“誕生”到

3、“死亡”通常經(jīng)歷下面的階段:n對(duì)象創(chuàng)建根據(jù)對(duì)象類型為對(duì)象分配所存儲(chǔ)空間。n對(duì)象初始化給整型、實(shí)型、字符型、指針變量賦初值;給對(duì)象的數(shù)據(jù)成員賦初值n對(duì)象的使用在程序中存取該對(duì)象n對(duì)象的善后清理對(duì)象被回收前必要的善后處理,基本類型對(duì)象無需此步驟n回收對(duì)象所占空間初始化C+中,初始化基本數(shù)據(jù)類型變量的規(guī)則和C語言相同。int a=6;/變量初始化int b; /是否初始化依賴于變量是全局的還是局部的int* pc = new int; /新分配的整型變量不作初始化C+中,結(jié)構(gòu)變量初始化可以按照C語言中結(jié)構(gòu)變量初始化的方式進(jìn)行。struct student char* name; char* id;f

4、loat score;student s1 = “王二”, “02201009”, 89.3;初始化由于類的數(shù)據(jù)成員有不同的存取權(quán)限,因而不能象初始化結(jié)構(gòu)那樣對(duì)類對(duì)象進(jìn)行初始化。class TDate public: void Set( int, int, int ); int IsLeapYear(); void Print();private: int year; int month; int day;/下面初始化對(duì)象的方式是錯(cuò)誤/的,因?yàn)榭蛻舸嫒×藢?duì)象的私/有數(shù)據(jù)成員。C+中把數(shù)據(jù)成員/設(shè)為私有成員,為的是向客戶/隱層對(duì)象內(nèi)部的實(shí)現(xiàn)細(xì)節(jié)TDate d1 = 2003, 9, 27;初始化

5、可以在定義類的時(shí)侯,專門定義初始化對(duì)象的成員函數(shù),負(fù)責(zé)對(duì)象的初始化工作。例如:void TDate:Set( int m, int d, int y ) month = m; day = d; year = y;但是這樣程序員需要在每次創(chuàng)建對(duì)象后調(diào)用用于初始化的成員函數(shù)。例如:TDate d;d.Set(9,27,2003);TDate *pd = new TDate;pd-Set(9,29,2003);面向?qū)ο蟮某绦蛟O(shè)計(jì)思想認(rèn)為對(duì)象的初始化工作應(yīng)由編譯程序負(fù)責(zé)處理,應(yīng)該在對(duì)象創(chuàng)建后立即進(jìn)行初始化。構(gòu)造函數(shù)C+要求為每個(gè)類定義構(gòu)造函數(shù),負(fù)責(zé)該類對(duì)象的初始化工作。構(gòu)造函數(shù)是類的一個(gè)特殊成員函數(shù)。

6、函數(shù)名和類名相同,且沒有返回值,可以在類的內(nèi)部進(jìn)行定義,也可以在外部進(jìn)行定義。class TDate public: TDate(); int IsLeapYear(); void Print();private: int year; int month; int day; TDate:TDate() year = 2000; month = 1; day = 1;void TDate:TDate() year = 2000; month = 1; day = 1;構(gòu)造函數(shù)構(gòu)造函數(shù)在對(duì)象創(chuàng)建時(shí)自動(dòng)被調(diào)用。程序員不能在程序中調(diào)用構(gòu)造函數(shù)。TDate gd; /構(gòu)造函數(shù)TDate()被自動(dòng)調(diào)用in

7、t main() TDate ld; /構(gòu)造函數(shù)TDate()被自動(dòng)調(diào)用 . TDate *pd = new TDate; /構(gòu)造函數(shù)TDate()被自動(dòng)調(diào)用 . delete pd; .構(gòu)造函數(shù)的重載構(gòu)造函數(shù)可以重載以滿足不同的對(duì)象初始化需求。(即為一個(gè)類定義多個(gè)構(gòu)造函數(shù),但各個(gè)構(gòu)造函數(shù)帶不同類型或數(shù)量的參數(shù))class TDate public: TDate(); TDate(int, int, int ); int IsLeapYear(); void Print();private: int year; int month; int day; TDate:TDate() year =

8、2000; month = 1; day = 1;TDate:TDate(int m, int d, int y) year = y; month = m; day = d;構(gòu)造函數(shù)的重載如果定義了有參數(shù)的構(gòu)造函數(shù),則定義對(duì)象時(shí),可以給定參數(shù)。編譯程序根據(jù)重載函數(shù)的規(guī)則決定應(yīng)該調(diào)用哪個(gè)構(gòu)造函數(shù)。例如: TDate d1(9,27,2003);/調(diào)用構(gòu)造函數(shù)TDate(int, int, int) TDate d2;/調(diào)用構(gòu)造函數(shù)TDate() TDate d3(2003);/錯(cuò)誤,編譯程序找不到只有一個(gè)參數(shù)的構(gòu)造函數(shù)程序員不能直接顯式調(diào)用構(gòu)造函數(shù)。TDate d2; d2.TDate(9,27

9、,2003);/錯(cuò)誤,編譯出錯(cuò)構(gòu)造函數(shù)的重載可以為構(gòu)造函數(shù)的參數(shù)指定默認(rèn)值。但應(yīng)注意重載和默認(rèn)值有可能發(fā)生沖突。TDate:TDate(int m, int d = 1, int y = 2000) year = y; month = m; day = d;.TDate d(5);/調(diào)用構(gòu)造函數(shù)Tdate(5,1,2000).默認(rèn)構(gòu)造函數(shù)每個(gè)類必須有構(gòu)造函數(shù)。沒有構(gòu)造函數(shù),對(duì)象不能被創(chuàng)建。如果程序員沒有提供任何構(gòu)造函數(shù),編譯程序?qū)⒆詣?dòng)創(chuàng)建一個(gè)沒有參數(shù)的構(gòu)造函數(shù),該構(gòu)造函數(shù)即為默認(rèn)構(gòu)造函數(shù)。默認(rèn)構(gòu)造函數(shù)不作任何初始化工作。其函數(shù)體為空。class TDate public: void Set(

10、int, int, int ); int IsLeapYear(); void Print();private: int year; int month; int day;TDate:TDate() /默認(rèn)構(gòu)造函數(shù)默認(rèn)構(gòu)造函數(shù)程序員一旦定義了構(gòu)造函數(shù),不管是否有參數(shù)。編譯程序不再提供默認(rèn)構(gòu)造函數(shù)。class TDate public: TDate(int, int, int );/帶參數(shù) int IsLeapYear(); void Print();private: int year; int month; int day; .TDate d; /編譯會(huì)出錯(cuò),沒有可用的構(gòu)造/函數(shù),對(duì)象不能被創(chuàng)

11、建.析構(gòu)函數(shù)面向?qū)ο蟮某绦蛟O(shè)計(jì)思想認(rèn)為在對(duì)象所占存儲(chǔ)空間被回收前,應(yīng)對(duì)對(duì)象作必要的善后清理,且善后工作應(yīng)由編譯程序負(fù)責(zé)處理。C+中可以為每個(gè)類定義析構(gòu)函數(shù),負(fù)責(zé)該類對(duì)象所占存儲(chǔ)空間回收前的清理工作。析構(gòu)函數(shù)是類的一個(gè)特殊成員函數(shù)。函數(shù)名由加類名構(gòu)成,沒有返回值,沒有參數(shù),不能重載,可以在類的內(nèi)部進(jìn)行定義,也可以在外部進(jìn)行定義。析構(gòu)函數(shù)在對(duì)象生命結(jié)束時(shí)自動(dòng)被調(diào)用(即所占存儲(chǔ)空間被回收前)。程序員不能直接顯式調(diào)用析構(gòu)函數(shù)。析構(gòu)函數(shù)class TDate public: TDate(int, int, int ); int IsLeapYear(); void Print(); TDate();/析

12、構(gòu)函數(shù) private: int year; int month; int day;TDate:TDate() cout“bye!”endl;int TDate:TDate() cout“bye!”endl;TDate:TDate(int i) cout“bye!”endl;析構(gòu)函數(shù)TDate gd; int main() TDate ld; . TDate *pd = new TDate; . delete pd;/為動(dòng)態(tài)分配的對(duì)象(pd指向的對(duì)象)自動(dòng)調(diào)用析構(gòu)函數(shù)TDate() . /為局部對(duì)象ld自動(dòng)調(diào)用析構(gòu)函數(shù)TDate()/為全局對(duì)象gd自動(dòng)調(diào)用析構(gòu)函數(shù)TDate()析構(gòu)函數(shù)析構(gòu)函數(shù)

13、有時(shí)候顯得很重要,例如在類中有指針成員,且該指針指向了一片動(dòng)態(tài)分配的存儲(chǔ)空間,此時(shí)應(yīng)定義析構(gòu)函數(shù),并且在析構(gòu)函數(shù)中釋放動(dòng)態(tài)分配的存儲(chǔ)空間,否則就會(huì)引起內(nèi)存泄漏問題。class XYZ public: XYZ(); XYZ();private: char* cptr;XYZ:XYZ() cptr = new char100;XYZ:XYZ() delete cptr ;int func() XYZ a; .new和delete 為什么C+中不使用malloc()和free()而使用new和delete來創(chuàng)建動(dòng)態(tài)對(duì)象和回收動(dòng)態(tài)對(duì)象? 用new創(chuàng)建動(dòng)態(tài)對(duì)象自動(dòng)調(diào)用構(gòu)造函數(shù)。而malloc()不自動(dòng)調(diào)

14、用構(gòu)造函數(shù)。 用delete回收動(dòng)態(tài)對(duì)象自動(dòng)調(diào)用析構(gòu)函數(shù)。而free()不自動(dòng)調(diào)用析構(gòu)函數(shù)。對(duì)象數(shù)組的構(gòu)造和析構(gòu)可以定義對(duì)象的數(shù)組,此時(shí)要為每一個(gè)數(shù)組元素調(diào)用構(gòu)造函數(shù)。TDate d100; /調(diào)用100 次構(gòu)造函數(shù)對(duì)象數(shù)組生命期終結(jié)時(shí),也要為每一個(gè)數(shù)組元素調(diào)用析構(gòu)函數(shù)。void func() TDate d100; /調(diào)用100 次構(gòu)造函數(shù) /調(diào)用100 次析構(gòu)函數(shù) 對(duì)象成員的構(gòu)造和析構(gòu)C+中,每個(gè)類的構(gòu)造函數(shù)只負(fù)責(zé)初始化該類的對(duì)象,若類中某個(gè)成員也是對(duì)象,則該成員由成員自身的構(gòu)造函數(shù)完成初始化。若類中某個(gè)成員是一個(gè)對(duì)象,則調(diào)用該類的構(gòu)造造函數(shù)前會(huì)自動(dòng)調(diào)用對(duì)象成員的構(gòu)造函數(shù)。class B

15、public: B() b = 0; coutin B. endl; private: int b;class A public: A() a = 0; cout in A. endl; private: B x;/成員x是一個(gè)B類對(duì)象 int a;int main() A obj1; / 程序運(yùn)行后,控制臺(tái)窗口會(huì)如何顯示/顯示如下:in B.in A.對(duì)象成員的構(gòu)造和析構(gòu)若類中某個(gè)成員是一個(gè)對(duì)象,則調(diào)用該類的析構(gòu)函數(shù)后會(huì)自動(dòng)調(diào)用對(duì)象成員的析構(gòu)函數(shù)。(和構(gòu)造函數(shù)相比,調(diào)用順序相反)class B public: B() b = 0; cout in B. endl; B() cout out

16、B. endl; private: int b;class A public: A() a = 0; coutin A.endl; A() coutout A.endl; private: B x;/成員x是對(duì)象 int a;int main() A obj1; / 程序運(yùn)行后,控制臺(tái)窗口會(huì)如何顯示/顯示如下:in B.in A.out A.out B.對(duì)象成員的構(gòu)造和析構(gòu)如何調(diào)用對(duì)象成員的有參數(shù)的構(gòu)造函數(shù)?class B public: B() b = 0; coutb=bendl; B( int bi ) b = bi; coutb=bendl; private: int b;class

17、A public: A() a = 0; cout“a=aendl; A( int ai) a = ai; cout “a=aendl; A( int ai, int bi):x(bi) a = ai; cout “a=aendl; private: B x;/成員x是一個(gè)B類對(duì)象 int a;int main() A obj1; A obj2(10); A obj3(10, 20);/ 程序運(yùn)行后,控制臺(tái)窗口會(huì)如何顯示/顯示如下:b=0 a=0 b=0 a=10 b=20 a=10 拷貝構(gòu)造函數(shù)在C語言中,可以用已定義的變量初始化同類型變量。如:int a = 5;int b = a;在C+

18、中,也可用已定義的對(duì)象初始化同類對(duì)象。如:TDate d1(2,10,1997);TDate d2(d1);也可以寫做:TDate d1(2,10,1997);TDate d2 = d1;用一個(gè)對(duì)象初始化另一個(gè)對(duì)象,通常意味著數(shù)據(jù)成員的逐個(gè)復(fù)制。用一個(gè)對(duì)象初始化另一個(gè)對(duì)象需要為類定義拷貝構(gòu)造函數(shù)。在初始化時(shí)會(huì)自動(dòng)調(diào)用拷貝構(gòu)造函數(shù),程序員不能直接顯式調(diào)用拷貝構(gòu)造函數(shù)??截悩?gòu)造函數(shù)拷貝構(gòu)造函數(shù)是類的構(gòu)造函數(shù),帶有一個(gè)參數(shù),參數(shù)是是該類對(duì)象的引用。class T int a;public:T() a= 0; T(T& t) /拷貝構(gòu)造函數(shù) a = t.a .;拷貝構(gòu)造函數(shù)class TDat

19、e public:TDate();TDate(int, int, int );TDate(TDate& );int IsLeapYear();void Print();TDate();private:int year;int month;int day; .TDate:TDate( TDate& d ) year = d.year;month = d.month;day = d.day;cout“copying.”endl;.拷貝構(gòu)造函數(shù)在下列情況下,會(huì)自動(dòng)調(diào)用拷貝構(gòu)造函數(shù):a)用一個(gè)已經(jīng)存在的對(duì)象初始化一個(gè)新創(chuàng)建的同類對(duì)象。b)對(duì)象作為函數(shù)參數(shù)時(shí),如果采用傳值調(diào)用,將建立對(duì)象

20、的副本,該副本的構(gòu)建需要調(diào)用拷貝構(gòu)造函數(shù)。int func( TDate d) int main() TDate ld; func(ld); ./輸出為copying.c)某個(gè)函數(shù)的返回值是一個(gè)對(duì)象,也要?jiǎng)?chuàng)建對(duì)象副本,此時(shí)也需要自動(dòng)調(diào)用拷貝構(gòu)造函數(shù)。TDate func() TDate td; . return td;int main() TDate ld=func(); ./輸出如下:copying.copying.默認(rèn)拷貝構(gòu)造函數(shù)程序員如果沒有為類定義拷貝構(gòu)造函數(shù),編譯程序會(huì)自動(dòng)定義默認(rèn)拷貝構(gòu)造函數(shù)。默認(rèn)拷貝構(gòu)造函數(shù)的語義是(數(shù)據(jù))成員逐個(gè)依次拷貝。如果程序員沒有為類TDate定義拷貝構(gòu)造函數(shù),則編譯程序定義的默認(rèn)拷貝構(gòu)造函數(shù)如

溫馨提示

  • 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. 人人文庫網(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)論