C++動(dòng)態(tài)內(nèi)存分配_第1頁
C++動(dòng)態(tài)內(nèi)存分配_第2頁
C++動(dòng)態(tài)內(nèi)存分配_第3頁
C++動(dòng)態(tài)內(nèi)存分配_第4頁
C++動(dòng)態(tài)內(nèi)存分配_第5頁
已閱讀5頁,還剩25頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、 動(dòng)態(tài)內(nèi)存分配動(dòng)態(tài)內(nèi)存分配 本章首先介紹程序運(yùn)行時(shí)本章首先介紹程序運(yùn)行時(shí)動(dòng)態(tài)內(nèi)存分配動(dòng)態(tài)內(nèi)存分配(dynamic memory allocationdynamic memory allocation)的概念與方法。到)的概念與方法。到目前為止,本教材介紹的程序設(shè)計(jì)中,變量和對(duì)象在目前為止,本教材介紹的程序設(shè)計(jì)中,變量和對(duì)象在內(nèi)存中的分配內(nèi)存中的分配都是編譯器在都是編譯器在編譯程序時(shí)安排編譯程序時(shí)安排好了的,好了的,這帶來了極大的不便,如數(shù)組必須大開小用,指針必這帶來了極大的不便,如數(shù)組必須大開小用,指針必須指向一個(gè)已經(jīng)存在的變量或?qū)ο?。?dòng)態(tài)內(nèi)存分配解須指向一個(gè)已經(jīng)存在的變量或?qū)ο蟆?dòng)態(tài)內(nèi)存分配

2、解決了這個(gè)問題。決了這個(gè)問題。 本章將進(jìn)一步討論拷貝構(gòu)造函數(shù);本章將進(jìn)一步討論拷貝構(gòu)造函數(shù); 還要學(xué)習(xí)更多有關(guān)還要學(xué)習(xí)更多有關(guān)數(shù)據(jù)結(jié)構(gòu)數(shù)據(jù)結(jié)構(gòu)的基本知識(shí),包括的基本知識(shí),包括棧,棧,隊(duì),二叉樹隊(duì),二叉樹等的基本算法和應(yīng)用。等的基本算法和應(yīng)用。模板模板是標(biāo)準(zhǔn)是標(biāo)準(zhǔn)C+C+實(shí)實(shí)現(xiàn)代碼復(fù)用的有力工具,特別是有關(guān)數(shù)據(jù)結(jié)構(gòu)的算法。現(xiàn)代碼復(fù)用的有力工具,特別是有關(guān)數(shù)據(jù)結(jié)構(gòu)的算法。本章繼續(xù)本章繼續(xù)使用模板介紹算法使用模板介紹算法。1 堆內(nèi)存分配堆內(nèi)存分配 5 MFC對(duì)象和對(duì)象和Windows對(duì)象的關(guān)系對(duì)象的關(guān)系 4二叉樹二叉樹 3 棧與隊(duì)列的基本操作棧與隊(duì)列的基本操作及其應(yīng)用及其應(yīng)用 2 鏈表與鏈表的基本操

3、作鏈表與鏈表的基本操作 動(dòng)態(tài)內(nèi)存分配動(dòng)態(tài)內(nèi)存分配 6 圖書流通圖書流通管理系統(tǒng)設(shè)計(jì)管理系統(tǒng)設(shè)計(jì)鏈表類應(yīng)用鏈表類應(yīng)用 1 堆內(nèi)存分配堆內(nèi)存分配 C/C+ C/C+定義了定義了4 4個(gè)內(nèi)存區(qū)間:代碼區(qū),全局變個(gè)內(nèi)存區(qū)間:代碼區(qū),全局變量與靜態(tài)變量區(qū),局部變量區(qū)即棧區(qū),量與靜態(tài)變量區(qū),局部變量區(qū)即棧區(qū),動(dòng)態(tài)存儲(chǔ)動(dòng)態(tài)存儲(chǔ)區(qū),即堆(區(qū),即堆(heapheap)區(qū)或自由存儲(chǔ)區(qū)()區(qū)或自由存儲(chǔ)區(qū)(free storefree store)。1.1堆內(nèi)存的分配與釋放堆內(nèi)存的分配與釋放 1.2 堆對(duì)象與構(gòu)造函數(shù)堆對(duì)象與構(gòu)造函數(shù) 1.3 淺拷貝與深拷貝淺拷貝與深拷貝 通常定義變量(或?qū)ο螅幾g器在編通常定義變量

4、(或?qū)ο螅幾g器在編譯時(shí)都可以根據(jù)該變量(或?qū)ο螅┑念愋椭浪鑳?nèi)譯時(shí)都可以根據(jù)該變量(或?qū)ο螅┑念愋椭浪鑳?nèi)存空間的大小,從而系統(tǒng)在適當(dāng)?shù)臅r(shí)候?yàn)樗麄兎峙浯_存空間的大小,從而系統(tǒng)在適當(dāng)?shù)臅r(shí)候?yàn)樗麄兎峙浯_定的存儲(chǔ)空間。這種內(nèi)存分配稱為定的存儲(chǔ)空間。這種內(nèi)存分配稱為靜態(tài)存儲(chǔ)分配;靜態(tài)存儲(chǔ)分配; 有些操作對(duì)象只在程序運(yùn)行時(shí)才能確定,這樣編有些操作對(duì)象只在程序運(yùn)行時(shí)才能確定,這樣編譯時(shí)就無法為他們預(yù)定存儲(chǔ)空間,只能在程序運(yùn)行時(shí),譯時(shí)就無法為他們預(yù)定存儲(chǔ)空間,只能在程序運(yùn)行時(shí),系統(tǒng)根據(jù)運(yùn)行時(shí)的要求進(jìn)行內(nèi)存分配,這種方法稱為系統(tǒng)根據(jù)運(yùn)行時(shí)的要求進(jìn)行內(nèi)存分配,這種方法稱為動(dòng)態(tài)存儲(chǔ)分配。動(dòng)態(tài)存儲(chǔ)分配。所有

5、動(dòng)態(tài)存儲(chǔ)分配都在堆區(qū)中進(jìn)行。所有動(dòng)態(tài)存儲(chǔ)分配都在堆區(qū)中進(jìn)行。 當(dāng)程序運(yùn)行到需要一個(gè)動(dòng)態(tài)分配的變量或?qū)ο髸r(shí),當(dāng)程序運(yùn)行到需要一個(gè)動(dòng)態(tài)分配的變量或?qū)ο髸r(shí),必須向系統(tǒng)必須向系統(tǒng)申請(qǐng)取得申請(qǐng)取得堆中的一塊所需大小的存貯空間,堆中的一塊所需大小的存貯空間,用于存貯該變量或?qū)ο蟆.?dāng)不再使用該變量或?qū)ο髸r(shí),用于存貯該變量或?qū)ο蟆.?dāng)不再使用該變量或?qū)ο髸r(shí),也就是它的生命結(jié)束時(shí),要也就是它的生命結(jié)束時(shí),要顯式釋放顯式釋放它所占用的存貯它所占用的存貯空間,這樣系統(tǒng)就能對(duì)該堆空間進(jìn)行再次分配,做到空間,這樣系統(tǒng)就能對(duì)該堆空間進(jìn)行再次分配,做到重復(fù)使用有限的資源。重復(fù)使用有限的資源。堆的概念1.1 堆內(nèi)存的分配與釋放

6、堆內(nèi)存的分配與釋放 在在C+中,申請(qǐng)和釋放堆中分配的存貯空間,中,申請(qǐng)和釋放堆中分配的存貯空間,分別使用分別使用new和和delete的兩個(gè)運(yùn)算符來完成:的兩個(gè)運(yùn)算符來完成:指針變量名指針變量名=new 類型名類型名(初始化式初始化式); delete 指針名指針名;例如:例如:1 1、 int int * *pi=new int(0);pi=new int(0); 它與下列代碼序列大體等價(jià):它與下列代碼序列大體等價(jià): 2 2、int ival=0, int ival=0, * *pi=&ival;pi=&ival;區(qū)別區(qū)別:pipi所指向的變量是由庫操作符所指向的變量是由庫操

7、作符new()new()分配的,分配的,位于程序的位于程序的堆堆區(qū)中,并且區(qū)中,并且該對(duì)象未命名該對(duì)象未命名。 堆空間申請(qǐng)、釋放的方法1 1、newnew運(yùn)算符運(yùn)算符返回的是一個(gè)指向所分配類型變量(對(duì)返回的是一個(gè)指向所分配類型變量(對(duì)象)的指針象)的指針。對(duì)所創(chuàng)建的變量或?qū)ο螅际峭ㄟ^該指。對(duì)所創(chuàng)建的變量或?qū)ο螅际峭ㄟ^該指針來間接操作的,而針來間接操作的,而動(dòng)態(tài)創(chuàng)建的對(duì)象本身沒有名字。動(dòng)態(tài)創(chuàng)建的對(duì)象本身沒有名字。2 2、一般定義變量和對(duì)象時(shí)要用標(biāo)識(shí)符命名,稱一般定義變量和對(duì)象時(shí)要用標(biāo)識(shí)符命名,稱命名命名對(duì)象對(duì)象,而動(dòng)態(tài)的稱,而動(dòng)態(tài)的稱無名對(duì)象無名對(duì)象( (請(qǐng)注意與棧區(qū)中的臨時(shí)請(qǐng)注意與棧區(qū)中的

8、臨時(shí)對(duì)象的區(qū)別,兩者完全不同:生命期不同,操作方法對(duì)象的區(qū)別,兩者完全不同:生命期不同,操作方法不同,臨時(shí)變量對(duì)程序員是透明的不同,臨時(shí)變量對(duì)程序員是透明的) )。3 3、堆區(qū)是不會(huì)在分配時(shí)做自動(dòng)初始化的(包括清、堆區(qū)是不會(huì)在分配時(shí)做自動(dòng)初始化的(包括清零),所以必須用初始化式零),所以必須用初始化式(initializer)(initializer)來顯式初來顯式初始化。始化。newnew表達(dá)式的操作序列如下:表達(dá)式的操作序列如下:從堆區(qū)分配對(duì)象,從堆區(qū)分配對(duì)象,然后用括號(hào)中的值初始化該對(duì)象然后用括號(hào)中的值初始化該對(duì)象。堆空間申請(qǐng)、釋放說明堆堆i用初始化式用初始化式(initializer)

9、(initializer)來顯式初始化來顯式初始化 int int * *pi=new int(0);pi=new int(0);當(dāng)當(dāng)pipi生命周期結(jié)束時(shí),生命周期結(jié)束時(shí),必須釋放必須釋放pipi所指向的目標(biāo):所指向的目標(biāo): delete pi;delete pi;注意這時(shí)釋放了注意這時(shí)釋放了pipi所指的目標(biāo)的內(nèi)存空間,也就是所指的目標(biāo)的內(nèi)存空間,也就是撤銷了該目標(biāo),稱動(dòng)態(tài)內(nèi)存釋放(撤銷了該目標(biāo),稱動(dòng)態(tài)內(nèi)存釋放(dynamic memory dynamic memory deallocationdeallocation),但),但指針指針pipi本身并沒有撤銷本身并沒有撤銷,它自,它自己仍

10、然存在,該指針?biāo)純?nèi)存空間并未釋放。己仍然存在,該指針?biāo)純?nèi)存空間并未釋放。 堆空間申請(qǐng)、釋放演示1 1、申請(qǐng)數(shù)組空間:、申請(qǐng)數(shù)組空間:指針變量名指針變量名=new =new 類型名類型名 下標(biāo)表達(dá)式下標(biāo)表達(dá)式;注意:注意:“下標(biāo)表達(dá)式下標(biāo)表達(dá)式”不是常量表達(dá)式不是常量表達(dá)式,即它的值不,即它的值不必在編譯時(shí)確定,可以在運(yùn)行時(shí)確定。必在編譯時(shí)確定,可以在運(yùn)行時(shí)確定。2 2、釋放數(shù)組空間:、釋放數(shù)組空間:delete delete 指向該數(shù)組的指針變量名指向該數(shù)組的指針變量名; ;注意:注意:方括號(hào)方括號(hào)非常重要的,如果非常重要的,如果delete語句中少了方語句中少了方括號(hào),因編譯器認(rèn)為該指針

11、是指向數(shù)組第一個(gè)元素的,括號(hào),因編譯器認(rèn)為該指針是指向數(shù)組第一個(gè)元素的,會(huì)產(chǎn)生回收不徹底的問題(只回收了第一個(gè)元素所占會(huì)產(chǎn)生回收不徹底的問題(只回收了第一個(gè)元素所占空間),加了方括號(hào)后就轉(zhuǎn)化為指向數(shù)組的指針,回空間),加了方括號(hào)后就轉(zhuǎn)化為指向數(shù)組的指針,回收整個(gè)數(shù)組。收整個(gè)數(shù)組。delete 的方括號(hào)中的方括號(hào)中不需要填數(shù)組元素不需要填數(shù)組元素?cái)?shù)數(shù),系統(tǒng)自知。即使寫了,編譯器也忽略。,系統(tǒng)自知。即使寫了,編譯器也忽略。在堆中建立動(dòng)態(tài)一維數(shù)組在堆中建立動(dòng)態(tài)一維數(shù)組#include #include void main()int n;char *pc;cout請(qǐng)輸入動(dòng)態(tài)數(shù)組的元素個(gè)數(shù)請(qǐng)輸入動(dòng)態(tài)數(shù)組

12、的元素個(gè)數(shù)n; /n在運(yùn)行時(shí)確定,在運(yùn)行時(shí)確定,可輸入可輸入17pc=new charn; /申請(qǐng)申請(qǐng)17個(gè)字符(可裝個(gè)字符(可裝8個(gè)漢個(gè)漢字和一個(gè)結(jié)束符)的內(nèi)存空間字和一個(gè)結(jié)束符)的內(nèi)存空間strcpy(pc,“堆內(nèi)存的動(dòng)態(tài)分配堆內(nèi)存的動(dòng)態(tài)分配”);/coutpcendl;delete pc;/釋放釋放pc所指向的所指向的n個(gè)字符的內(nèi)存?zhèn)€字符的內(nèi)存空間空間return ;【例【例1】動(dòng)態(tài)一維數(shù)組】動(dòng)態(tài)一維數(shù)組的建立與撤銷的建立與撤銷1.變量變量n在編譯時(shí)沒有確定的值,而是在運(yùn)行中輸入,在編譯時(shí)沒有確定的值,而是在運(yùn)行中輸入,按運(yùn)行時(shí)所需分配堆空間按運(yùn)行時(shí)所需分配堆空間,這一點(diǎn)是動(dòng)態(tài)分配的優(yōu),

13、這一點(diǎn)是動(dòng)態(tài)分配的優(yōu)點(diǎn),可克服數(shù)組點(diǎn),可克服數(shù)組“大開小用大開小用”的弊端,在表、排序的弊端,在表、排序與查找中的算法,若用動(dòng)態(tài)數(shù)組,通用性更佳。一與查找中的算法,若用動(dòng)態(tài)數(shù)組,通用性更佳。一定注意:定注意:delete pc是將是將n個(gè)字符的空間釋放,而個(gè)字符的空間釋放,而用用delete pc則只釋放了一個(gè)字符的空間則只釋放了一個(gè)字符的空間;2.如果有一個(gè)如果有一個(gè)char *pc1,令,令pc1=p,同樣可用,同樣可用delete pc1來釋放該空間。盡管來釋放該空間。盡管C+不對(duì)數(shù)組作不對(duì)數(shù)組作邊界檢查,但邊界檢查,但在堆空間分配時(shí),對(duì)數(shù)組分配空間大在堆空間分配時(shí),對(duì)數(shù)組分配空間大小是

14、紀(jì)錄在案的小是紀(jì)錄在案的。3.沒有初始化式(沒有初始化式(initializer),),不可對(duì)數(shù)組初始化不可對(duì)數(shù)組初始化。 動(dòng)態(tài)一維數(shù)組的說明動(dòng)態(tài)一維數(shù)組的說明new 類型名類型名下標(biāo)表達(dá)式下標(biāo)表達(dá)式1 下標(biāo)表達(dá)式下標(biāo)表達(dá)式2;例如:建立一個(gè)動(dòng)態(tài)三維數(shù)組例如:建立一個(gè)動(dòng)態(tài)三維數(shù)組float (*cp)3020 ; /指向一個(gè)指向一個(gè)30行行20列數(shù)組列數(shù)組 /的指針,指向二維數(shù)組的指針的指針,指向二維數(shù)組的指針cp=new float 15 30 20; /建立由建立由15個(gè)個(gè)30*20數(shù)組組成的數(shù)組;數(shù)組組成的數(shù)組;注意:注意:cp等效于三維數(shù)組名,但沒有指出其邊界,等效于三維數(shù)組名,但沒有

15、指出其邊界,即最高維的元素?cái)?shù)量,就像指向字符的指針即等效即最高維的元素?cái)?shù)量,就像指向字符的指針即等效一個(gè)字符串一個(gè)字符串,不要把指向字符的指針,說成指向字符不要把指向字符的指針,說成指向字符串的指針。這與數(shù)組的嵌套定義相一致。串的指針。這與數(shù)組的嵌套定義相一致。在堆中建立動(dòng)態(tài)多維數(shù)組在堆中建立動(dòng)態(tài)多維數(shù)組 float(*cp) 30 20; /三級(jí)指針;三級(jí)指針; float (*bp) 20; /二級(jí)指針;二級(jí)指針; cp=new float 1 20 30; bp=new float 30 20; 兩個(gè)數(shù)組都是由兩個(gè)數(shù)組都是由600個(gè)浮點(diǎn)數(shù)組成,前者是個(gè)浮點(diǎn)數(shù)組成,前者是只有只有一個(gè)元素的

16、三維數(shù)組一個(gè)元素的三維數(shù)組,每個(gè)元素為,每個(gè)元素為30行行20列列的二維數(shù)組,而另一個(gè)是有的二維數(shù)組,而另一個(gè)是有30個(gè)元素的二維數(shù)組個(gè)元素的二維數(shù)組,每個(gè)元素為每個(gè)元素為20個(gè)元素的一維數(shù)組。個(gè)元素的一維數(shù)組。 刪除這兩個(gè)動(dòng)態(tài)數(shù)組可用下式:刪除這兩個(gè)動(dòng)態(tài)數(shù)組可用下式:delete cp; /刪除(釋放)三維數(shù)組;刪除(釋放)三維數(shù)組;delete bp; /刪除(釋放)二維數(shù)組;刪除(釋放)二維數(shù)組;多維數(shù)組比較與辨識(shí)多維數(shù)組比較與辨識(shí)const int m=4,n=6; /行列數(shù)行列數(shù)/1、先看二維數(shù)組的動(dòng)態(tài)創(chuàng)建:、先看二維數(shù)組的動(dòng)態(tài)創(chuàng)建:void main() double *data;

17、 data = new double*m; /申請(qǐng)行申請(qǐng)行 if (data ) = 0) cout Could not allocate. bye .; exit(-1); for(int j=0;jm;j+) dataj = new doublen; /設(shè)置列設(shè)置列 if (dataj = 0) cout Could not allocate. Bye .; exit(-1); /空間申請(qǐng)結(jié)束,下為初始化空間申請(qǐng)結(jié)束,下為初始化 for (int i=0;im;i+) for (int j=0;jn;j+) dataij=i*n+j;【例【例2】 動(dòng)態(tài)創(chuàng)建和刪除動(dòng)態(tài)創(chuàng)建和刪除一個(gè)一個(gè)m*n

18、個(gè)元素的數(shù)組。個(gè)元素的數(shù)組。采用采用指針數(shù)組方式指針數(shù)組方式來完成來完成二維數(shù)組的動(dòng)態(tài)創(chuàng)建。二維數(shù)組的動(dòng)態(tài)創(chuàng)建。 display(data); /2、二維數(shù)組的輸出,此處略。、二維數(shù)組的輸出,此處略。/3、再、再看二維數(shù)組的撤銷與內(nèi)存釋放:看二維數(shù)組的撤銷與內(nèi)存釋放: for (int i=0;im;i+) delete datai; /注意撤銷次序,先列后行,注意撤銷次序,先列后行,與設(shè)置相反與設(shè)置相反 delete data; return; 二維數(shù)組的內(nèi)存釋放可以做成函數(shù),二維數(shù)組的內(nèi)存釋放可以做成函數(shù),調(diào)用語句調(diào)用語句de_allocate(data);void de_allocate

19、(double *data) for (int i=0;im;i+) delete datai; delete data; return; 在在VC+平臺(tái)上演示本例平臺(tái)上演示本例。動(dòng)態(tài)分配失敗。動(dòng)態(tài)分配失敗。返回一個(gè)空指針(返回一個(gè)空指針(NULL),),表示發(fā)生了異常,堆資源不足,分配失敗。表示發(fā)生了異常,堆資源不足,分配失敗。 data = new double*m; /申請(qǐng)行申請(qǐng)行 if (data ) = 0)指針刪除與堆空間釋放。刪除一個(gè)指針指針刪除與堆空間釋放。刪除一個(gè)指針p(delete p;)實(shí)際意思是刪除了)實(shí)際意思是刪除了p所指的目標(biāo)(變所指的目標(biāo)(變量或?qū)ο蟮龋?,釋放了?/p>

20、所占的堆空間,而量或?qū)ο蟮龋?,釋放了它所占的堆空間,而不是刪不是刪除本身,釋放堆空間后,成了空懸指針除本身,釋放堆空間后,成了空懸指針,不能,不能再通過再通過p使用該空間,在重新給使用該空間,在重新給p賦值前,也不能再賦值前,也不能再直接使用直接使用p。通過指針使堆空間,編程通過指針使堆空間,編程 中的幾個(gè)可能問題中的幾個(gè)可能問題內(nèi)存泄漏(內(nèi)存泄漏(memory leak)和重復(fù)釋放)和重復(fù)釋放。new與與delete 是配對(duì)使用的,是配對(duì)使用的, delete只能釋放堆空間。只能釋放堆空間。如果如果new返回的指針值丟失,則所分配的堆空間無返回的指針值丟失,則所分配的堆空間無法回收,稱內(nèi)存泄

21、漏,同一空間重復(fù)釋放也是危險(xiǎn)的,法回收,稱內(nèi)存泄漏,同一空間重復(fù)釋放也是危險(xiǎn)的,因?yàn)橐驗(yàn)樵摽臻g可能已另分配該空間可能已另分配,所以必須妥善保存,所以必須妥善保存new返回的指針,以保證不發(fā)生內(nèi)存泄漏,也必須保證不返回的指針,以保證不發(fā)生內(nèi)存泄漏,也必須保證不會(huì)重復(fù)釋放堆內(nèi)存空間。會(huì)重復(fù)釋放堆內(nèi)存空間。動(dòng)態(tài)分配的變量或?qū)ο蟮纳?。?dòng)態(tài)分配的變量或?qū)ο蟮纳凇o名對(duì)象的生無名對(duì)象的生命期并不依賴于建立它的作用域,比如在函數(shù)中建立命期并不依賴于建立它的作用域,比如在函數(shù)中建立的動(dòng)態(tài)對(duì)象在函數(shù)返回后仍可使用。的動(dòng)態(tài)對(duì)象在函數(shù)返回后仍可使用。我們也稱堆空間我們也稱堆空間為自由空間(為自由空間(fre

22、e store)就是這個(gè)原因。)就是這個(gè)原因。但必須記但必須記住釋放該對(duì)象所占堆空間,并只能釋放一次,在函數(shù)住釋放該對(duì)象所占堆空間,并只能釋放一次,在函數(shù)內(nèi)建立,而在函數(shù)外釋放是一件很容易內(nèi)建立,而在函數(shù)外釋放是一件很容易失控失控的事,往的事,往往會(huì)出錯(cuò)。往會(huì)出錯(cuò)。 1.2堆對(duì)象與構(gòu)造函數(shù)堆對(duì)象與構(gòu)造函數(shù) 通過通過newnew建立的建立的對(duì)象對(duì)象要調(diào)用構(gòu)造函數(shù),通過要調(diào)用構(gòu)造函數(shù),通過deleteedeletee刪除對(duì)象也要調(diào)用析構(gòu)函數(shù)。刪除對(duì)象也要調(diào)用析構(gòu)函數(shù)。CGoods *pc;pc=new CGoods; /分配堆空間,并構(gòu)造一個(gè)無名分配堆空間,并構(gòu)造一個(gè)無名 /的的CGoods對(duì)象;

23、對(duì)象;.delete pc; /先析構(gòu),然后將內(nèi)存空間返回給堆;先析構(gòu),然后將內(nèi)存空間返回給堆; 堆對(duì)象的生命期堆對(duì)象的生命期并不依賴于建立它的作用域,并不依賴于建立它的作用域,所以除非程序結(jié)束,堆對(duì)象(無名對(duì)象)的生命期所以除非程序結(jié)束,堆對(duì)象(無名對(duì)象)的生命期不會(huì)到期,并且需要顯式地用不會(huì)到期,并且需要顯式地用delete語句析構(gòu)堆對(duì)象,語句析構(gòu)堆對(duì)象,上面的堆對(duì)象在執(zhí)行上面的堆對(duì)象在執(zhí)行delete語句時(shí),語句時(shí),C+自動(dòng)調(diào)用其自動(dòng)調(diào)用其析構(gòu)函數(shù)。析構(gòu)函數(shù)。正因?yàn)闃?gòu)造函數(shù)可以有參數(shù),所以正因?yàn)闃?gòu)造函數(shù)可以有參數(shù),所以newnew后面類后面類(classclass)類型也可以有參數(shù)。這些

24、參數(shù)即構(gòu)造)類型也可以有參數(shù)。這些參數(shù)即構(gòu)造函數(shù)的參數(shù)。函數(shù)的參數(shù)。但對(duì)創(chuàng)建數(shù)組,則無參數(shù),并只調(diào)用缺省的構(gòu)造函但對(duì)創(chuàng)建數(shù)組,則無參數(shù),并只調(diào)用缺省的構(gòu)造函數(shù)。見下例類說明:數(shù)。見下例類說明:class CGoods char Name21; int Amount; float Price; float Total value;public: CGoods(); /缺省構(gòu)造函數(shù)。因已有其他構(gòu)造函數(shù),缺省構(gòu)造函數(shù)。因已有其他構(gòu)造函數(shù),系統(tǒng)不會(huì)再自動(dòng)生成缺省構(gòu)造,必須顯式說明。系統(tǒng)不會(huì)再自動(dòng)生成缺省構(gòu)造,必須顯式說明。 CGoods(char* name,int amount ,float pri

25、ce) strcpy(Name,name); Amount=amount; Price=price; Total_value=price*amount; ;/類聲明結(jié)束類聲明結(jié)束/下面注意如何使用:下面注意如何使用:void main() int n; CGoods *pc,*pc1,*pc2; pc=new CGoods(“夏利夏利2000”,10,118000); /調(diào)用三參數(shù)構(gòu)造函數(shù)調(diào)用三參數(shù)構(gòu)造函數(shù) pc1=new CGoods(); /調(diào)用缺省構(gòu)造函數(shù)調(diào)用缺省構(gòu)造函數(shù) cout輸入商品類數(shù)組元素?cái)?shù)輸入商品類數(shù)組元素?cái)?shù)n; pc2=new CGoodsn; /動(dòng)態(tài)建立數(shù)組,不能初始化,

26、調(diào)用動(dòng)態(tài)建立數(shù)組,不能初始化,調(diào)用n次缺省構(gòu)造函數(shù)次缺省構(gòu)造函數(shù) delete pc; delete pc1; delete pc2; 此例告訴我們堆對(duì)象的使用方法:此例告訴我們堆對(duì)象的使用方法:申請(qǐng)堆空間申請(qǐng)堆空間之后之后構(gòu)造函數(shù)運(yùn)行;構(gòu)造函數(shù)運(yùn)行;釋放堆空間釋放堆空間之前之前析構(gòu)函數(shù)運(yùn)行;析構(gòu)函數(shù)運(yùn)行;再次強(qiáng)調(diào):再次強(qiáng)調(diào):由堆區(qū)創(chuàng)建對(duì)象數(shù)組,只能由堆區(qū)創(chuàng)建對(duì)象數(shù)組,只能調(diào)用缺省的構(gòu)造函數(shù),不能調(diào)用其他任調(diào)用缺省的構(gòu)造函數(shù),不能調(diào)用其他任何構(gòu)造函數(shù)。如果沒有缺省的構(gòu)造函數(shù),何構(gòu)造函數(shù)。如果沒有缺省的構(gòu)造函數(shù),則不能創(chuàng)建對(duì)象數(shù)組則不能創(chuàng)建對(duì)象數(shù)組。1.3淺拷貝與深拷貝淺拷貝與深拷貝 對(duì)象的構(gòu)造

27、,也可以由對(duì)象的構(gòu)造,也可以由拷貝構(gòu)造函數(shù)拷貝構(gòu)造函數(shù)完成,即完成,即用一個(gè)對(duì)象的內(nèi)容去初始化另一個(gè)對(duì)象的內(nèi)容。用一個(gè)對(duì)象的內(nèi)容去初始化另一個(gè)對(duì)象的內(nèi)容。此時(shí),若此時(shí),若對(duì)象使用了堆空間(注意和對(duì)象使用了堆空間(注意和“堆對(duì)象堆對(duì)象”區(qū)分)區(qū)分),就有深、淺拷貝的問題,不清楚則很,就有深、淺拷貝的問題,不清楚則很容易出錯(cuò)。容易出錯(cuò)。1、什么是淺拷貝?、什么是淺拷貝?2、淺拷貝可能帶來什么問題?、淺拷貝可能帶來什么問題?3、什么是深拷貝?、什么是深拷貝?4、深拷貝的實(shí)現(xiàn)方法?、深拷貝的實(shí)現(xiàn)方法?缺省拷貝構(gòu)造函數(shù):缺省拷貝構(gòu)造函數(shù):用一個(gè)對(duì)象的內(nèi)容初始化另一個(gè)用一個(gè)對(duì)象的內(nèi)容初始化另一個(gè)同類對(duì)象,

28、也稱為缺省的同類對(duì)象,也稱為缺省的按成員拷貝,按成員拷貝,不是對(duì)整個(gè)不是對(duì)整個(gè)類對(duì)象的類對(duì)象的按位拷貝。按位拷貝。這種拷貝稱為這種拷貝稱為淺拷貝。淺拷貝。 class CGoods char *Name; /不同與不同與char Name21 ? int Amount; float Price; float Total_value;public: CGoods()Name=new char21; CGoods(CGoods & other) /缺省拷貝構(gòu)造內(nèi)容:缺省拷貝構(gòu)造內(nèi)容: this-Name=other.Name; this-Amount=other.Amount; this-

29、Price=other.Price; this-Total_value=other.Total_value;CGoods()delete Name;/析構(gòu)函數(shù)析構(gòu)函數(shù); /類聲明結(jié)束類聲明結(jié)束什么是淺拷貝?什么是淺拷貝?otherName堆字堆字符串符串拷貝前拷貝前堆堆字字符符串串otherName*thisName 拷貝后拷貝后 圖圖7.1 淺拷貝淺拷貝 對(duì)象對(duì)象pcName堆堆字字符符串串第一個(gè)對(duì)象第一個(gè)對(duì)象堆堆字字符符串串對(duì)象對(duì)象pcName對(duì)象對(duì)象pc1Name 兩個(gè)對(duì)象兩個(gè)對(duì)象 圖圖7.1 淺拷貝淺拷貝 void main()CGoods pc; /調(diào)用缺省構(gòu)造函數(shù)調(diào)用缺省構(gòu)造函數(shù)

30、CGoods pc1(pc); /調(diào)用拷貝構(gòu)造函數(shù)調(diào)用拷貝構(gòu)造函數(shù) /程序執(zhí)行完,對(duì)象程序執(zhí)行完,對(duì)象pc1pc1和和pcpc將被析構(gòu),此時(shí)出錯(cuò)。將被析構(gòu),此時(shí)出錯(cuò)。淺拷貝帶來的問題淺拷貝帶來的問題析構(gòu)時(shí),如用析構(gòu)時(shí),如用缺省的析構(gòu)函數(shù)缺省的析構(gòu)函數(shù),則動(dòng)態(tài)分配的堆空,則動(dòng)態(tài)分配的堆空 間不能回收。間不能回收。如果用如果用有有“delete Name;”語句的析構(gòu)函數(shù)語句的析構(gòu)函數(shù),則先,則先 析構(gòu)析構(gòu)pc1時(shí),堆空間已經(jīng)釋放,然后再析構(gòu)時(shí),堆空間已經(jīng)釋放,然后再析構(gòu)pc 時(shí)出現(xiàn)了二次釋放的問題。時(shí)出現(xiàn)了二次釋放的問題。這時(shí)就要重新定義拷貝構(gòu)造函數(shù),給每個(gè)對(duì)象獨(dú)這時(shí)就要重新定義拷貝構(gòu)造函數(shù),給

31、每個(gè)對(duì)象獨(dú) 立分配一個(gè)堆字符串,稱立分配一個(gè)堆字符串,稱深拷貝深拷貝。對(duì)象對(duì)象pcName堆字堆字符串符串拷貝前拷貝前堆堆字字符符串串對(duì)象對(duì)象pcName對(duì)象對(duì)象pc1Name 淺拷貝后淺拷貝后 圖圖7.1 淺拷貝淺拷貝 對(duì)象對(duì)象pcName堆字堆字符串符串拷貝前拷貝前堆字符串堆字符串對(duì)象對(duì)象pcName對(duì)象對(duì)象pc1Name 深拷貝后深拷貝后 圖圖7.1 深拷貝深拷貝 堆字符串堆字符串2深拷貝深拷貝自定義拷貝構(gòu)造自定義拷貝構(gòu)造CGoods(CGoods & other) /自定義拷貝構(gòu)造自定義拷貝構(gòu)造 this-Name=new char21; strcpy(this-Name,other.Name); this-Amount=other.Amount; this-Price=other.Price; this-Total_value=other.Total_value;/學(xué)生類定義:學(xué)生類定義:class studentchar *pName; /指針成員指針成員public:student();student(char *pname);student(student &s); /拷貝構(gòu)造函數(shù)拷貝構(gòu)造函數(shù)student();student & operator=(student &s); /

溫馨提示

  • 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)論