動(dòng)態(tài)內(nèi)存分配和深復(fù)制ppt課件_第1頁(yè)
動(dòng)態(tài)內(nèi)存分配和深復(fù)制ppt課件_第2頁(yè)
動(dòng)態(tài)內(nèi)存分配和深復(fù)制ppt課件_第3頁(yè)
動(dòng)態(tài)內(nèi)存分配和深復(fù)制ppt課件_第4頁(yè)
動(dòng)態(tài)內(nèi)存分配和深復(fù)制ppt課件_第5頁(yè)
已閱讀5頁(yè),還剩18頁(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)介

1、 動(dòng)態(tài)內(nèi)存分配動(dòng)態(tài)內(nèi)存分配本章首先引見(jiàn)程序運(yùn)轉(zhuǎn)時(shí)動(dòng)態(tài)內(nèi)存分配本章首先引見(jiàn)程序運(yùn)轉(zhuǎn)時(shí)動(dòng)態(tài)內(nèi)存分配dynamic dynamic memory allocationmemory allocation的概念與方法。到目前為止,本的概念與方法。到目前為止,本教材引見(jiàn)的程序設(shè)計(jì)中,變量和對(duì)象在內(nèi)存中的分配都教材引見(jiàn)的程序設(shè)計(jì)中,變量和對(duì)象在內(nèi)存中的分配都是編譯器在編譯程序時(shí)安排好了的,這帶來(lái)了極大的不是編譯器在編譯程序時(shí)安排好了的,這帶來(lái)了極大的不便,如數(shù)組必需大開(kāi)小用,指針必需指向一個(gè)曾經(jīng)存在便,如數(shù)組必需大開(kāi)小用,指針必需指向一個(gè)曾經(jīng)存在的變量或?qū)ο蟆?dòng)態(tài)內(nèi)存分配處理了這個(gè)問(wèn)題。本章將的變量或?qū)ο蟆?/p>

2、動(dòng)態(tài)內(nèi)存分配處理了這個(gè)問(wèn)題。本章將進(jìn)一步討論拷貝構(gòu)造函數(shù)。進(jìn)一步討論拷貝構(gòu)造函數(shù)。 堆內(nèi)存分配堆內(nèi)存分配 堆內(nèi)存的分配與釋放堆內(nèi)存的分配與釋放 堆對(duì)象與構(gòu)造函數(shù)堆對(duì)象與構(gòu)造函數(shù) 淺拷貝與深拷貝淺拷貝與深拷貝 C/C+C/C+定義了定義了4 4個(gè)內(nèi)存區(qū)間:代碼區(qū),個(gè)內(nèi)存區(qū)間:代碼區(qū),全局變量與靜態(tài)變量區(qū),部分變量區(qū)全局變量與靜態(tài)變量區(qū),部分變量區(qū)即棧區(qū),動(dòng)態(tài)存儲(chǔ)區(qū),即堆即棧區(qū),動(dòng)態(tài)存儲(chǔ)區(qū),即堆heapheap區(qū)或自在存儲(chǔ)區(qū)區(qū)或自在存儲(chǔ)區(qū)free storefree store。通常定義變量或?qū)ο?,編譯器在通常定義變量或?qū)ο?,編譯器在編譯時(shí)都可以根據(jù)該變量或?qū)ο缶幾g時(shí)都可以根據(jù)該變量或?qū)ο蟮念愋椭?/p>

3、道所需內(nèi)存空間的大小,從的類型知道所需內(nèi)存空間的大小,從而系統(tǒng)在適當(dāng)?shù)臅r(shí)候?yàn)樗麄兎峙浯_定而系統(tǒng)在適當(dāng)?shù)臅r(shí)候?yàn)樗麄兎峙浯_定的存儲(chǔ)空間。這種內(nèi)存分配稱為靜態(tài)的存儲(chǔ)空間。這種內(nèi)存分配稱為靜態(tài)存儲(chǔ)分配存儲(chǔ)分配有些操作對(duì)象只需在程序運(yùn)轉(zhuǎn)時(shí)才干有些操作對(duì)象只需在程序運(yùn)轉(zhuǎn)時(shí)才干確定,這樣編譯器在編譯時(shí)就無(wú)法為確定,這樣編譯器在編譯時(shí)就無(wú)法為他們預(yù)定存儲(chǔ)空間,只能在程序運(yùn)轉(zhuǎn)他們預(yù)定存儲(chǔ)空間,只能在程序運(yùn)轉(zhuǎn)時(shí),系統(tǒng)根據(jù)運(yùn)轉(zhuǎn)時(shí)的要求進(jìn)展內(nèi)存時(shí),系統(tǒng)根據(jù)運(yùn)轉(zhuǎn)時(shí)的要求進(jìn)展內(nèi)存分配,這種方法稱為動(dòng)態(tài)存儲(chǔ)分配。分配,這種方法稱為動(dòng)態(tài)存儲(chǔ)分配。一切動(dòng)態(tài)存儲(chǔ)分配都在堆區(qū)中進(jìn)展。一切動(dòng)態(tài)存儲(chǔ)分配都在堆區(qū)中進(jìn)展。 堆內(nèi)存的分配與

4、釋放堆內(nèi)存的分配與釋放當(dāng)程序運(yùn)轉(zhuǎn)到需求一個(gè)動(dòng)態(tài)分配的變量或?qū)ο髸r(shí),必需向系統(tǒng)懇求獲當(dāng)程序運(yùn)轉(zhuǎn)到需求一個(gè)動(dòng)態(tài)分配的變量或?qū)ο髸r(shí),必需向系統(tǒng)懇求獲得堆中的一塊所需大小的存貯空間,用于存貯該變量或?qū)ο?。?dāng)不再運(yùn)得堆中的一塊所需大小的存貯空間,用于存貯該變量或?qū)ο?。?dāng)不再運(yùn)用該變量或?qū)ο髸r(shí),也就是它的生命終了時(shí),要顯式釋放它所占用的存用該變量或?qū)ο髸r(shí),也就是它的生命終了時(shí),要顯式釋放它所占用的存貯空間,這樣系統(tǒng)就能對(duì)該堆空間進(jìn)展再次分配,做到反復(fù)運(yùn)用有限的貯空間,這樣系統(tǒng)就能對(duì)該堆空間進(jìn)展再次分配,做到反復(fù)運(yùn)用有限的資源。資源。在在C+中,懇求和釋放堆中分配的存貯空間,分別運(yùn)用中,懇求和釋放堆中分配的

5、存貯空間,分別運(yùn)用new和和delete的的兩個(gè)運(yùn)算符來(lái)完成,其運(yùn)用的格式如下:兩個(gè)運(yùn)算符來(lái)完成,其運(yùn)用的格式如下:指針變量名指針變量名=new 類型名類型名(初始化式初始化式);delete 指針名指針名;new運(yùn)算符前往的是一個(gè)指向所分配類型變量對(duì)象的指針。對(duì)所運(yùn)算符前往的是一個(gè)指向所分配類型變量對(duì)象的指針。對(duì)所創(chuàng)建的變量或?qū)ο?,都是?jīng)過(guò)該指針來(lái)間接操作的,而動(dòng)態(tài)創(chuàng)建的對(duì)象創(chuàng)建的變量或?qū)ο螅际墙?jīng)過(guò)該指針來(lái)間接操作的,而動(dòng)態(tài)創(chuàng)建的對(duì)象本身沒(méi)有名字。本身沒(méi)有名字。 堆內(nèi)存的分配與釋放普通定義變量和對(duì)象時(shí)要用標(biāo)識(shí)符命名,稱命名對(duì)象,而動(dòng)普通定義變量和對(duì)象時(shí)要用標(biāo)識(shí)符命名,稱命名對(duì)象,而動(dòng)態(tài)的稱

6、無(wú)名對(duì)象態(tài)的稱無(wú)名對(duì)象( (請(qǐng)留意與棧區(qū)中的暫時(shí)對(duì)象的區(qū)別,兩者完請(qǐng)留意與棧區(qū)中的暫時(shí)對(duì)象的區(qū)別,兩者完全不同:生命期不同,操作方法不同,暫時(shí)變量對(duì)程序員是全不同:生命期不同,操作方法不同,暫時(shí)變量對(duì)程序員是透明的透明的) )。堆區(qū)是不會(huì)自動(dòng)在分配時(shí)做初始化的包括清零,。堆區(qū)是不會(huì)自動(dòng)在分配時(shí)做初始化的包括清零,所以必需用初始化式所以必需用初始化式(initializer)(initializer)來(lái)顯式初始化。來(lái)顯式初始化。newnew表達(dá)表達(dá)式的操作序列如下:從堆區(qū)分配對(duì)象,然后用括號(hào)中的值初式的操作序列如下:從堆區(qū)分配對(duì)象,然后用括號(hào)中的值初始化該對(duì)象。從堆區(qū)分配對(duì)象時(shí),始化該對(duì)象。從堆

7、區(qū)分配對(duì)象時(shí),newnew表達(dá)式調(diào)用庫(kù)操作符表達(dá)式調(diào)用庫(kù)操作符new()new()。例如:。例如: int int * *pi=new int(0);pi=new int(0);它與以下代碼序列大體等價(jià):它與以下代碼序列大體等價(jià):int ival=0;int ival=0;int int * *pi=&ival;pi=&ival;只是只是pipi如今所指向的變量是由庫(kù)操作符如今所指向的變量是由庫(kù)操作符new()new()分配的,位于程分配的,位于程序的堆區(qū)中,并且該對(duì)象未命名。序的堆區(qū)中,并且該對(duì)象未命名。 堆內(nèi)存的分配與釋放堆堆i下面看演示:下面看演示:用初始化式用初始化式(

8、initializer)(initializer)來(lái)顯式初始化來(lái)顯式初始化 int int * *pi=new int(0);pi=new int(0);當(dāng)當(dāng)pipi生命周期終了時(shí),生命周期終了時(shí),必需釋放必需釋放pipi所指向的目的:所指向的目的: delete pi; delete pi;留意這時(shí)釋放了留意這時(shí)釋放了pipi所指的目的的內(nèi)存空間,也就是撤銷了所指的目的的內(nèi)存空間,也就是撤銷了該目的,稱動(dòng)態(tài)內(nèi)存釋放該目的,稱動(dòng)態(tài)內(nèi)存釋放dynamic memory dynamic memory deallocationdeallocation,但指針,但指針pipi本身并沒(méi)有撤銷,它本人依然

9、本身并沒(méi)有撤銷,它本人依然存在,該指針?biāo)純?nèi)存空間并未釋放。存在,該指針?biāo)純?nèi)存空間并未釋放。 堆內(nèi)存的分配與釋放堆內(nèi)存的分配與釋放對(duì)于數(shù)組進(jìn)展動(dòng)態(tài)分配的格式為:對(duì)于數(shù)組進(jìn)展動(dòng)態(tài)分配的格式為:指針變量名指針變量名=new =new 類型名類型名 下標(biāo)表達(dá)式下標(biāo)表達(dá)式;delete delete 指向該數(shù)組的指針變量名指向該數(shù)組的指針變量名; ;兩式中的方括號(hào)是非常重要的,兩者必需配對(duì)運(yùn)兩式中的方括號(hào)是非常重要的,兩者必需配對(duì)運(yùn)用,假設(shè)用,假設(shè)deletedelete語(yǔ)句中少了方括號(hào),因編譯器以語(yǔ)句中少了方括號(hào),因編譯器以為該指針是指向數(shù)組第一個(gè)元素的指針,會(huì)產(chǎn)生為該指針是指向數(shù)組第一個(gè)元素的指

10、針,會(huì)產(chǎn)生回收不徹底的問(wèn)題只回收了第一個(gè)元素所占空回收不徹底的問(wèn)題只回收了第一個(gè)元素所占空間,加了方括號(hào)后就轉(zhuǎn)化為指向數(shù)組的指針,間,加了方括號(hào)后就轉(zhuǎn)化為指向數(shù)組的指針,回收整個(gè)數(shù)組。回收整個(gè)數(shù)組。delete delete 的方括號(hào)中不需求填的方括號(hào)中不需求填數(shù)組元素?cái)?shù),系統(tǒng)自知。即使寫了,編譯器也忽數(shù)組元素?cái)?shù),系統(tǒng)自知。即使寫了,編譯器也忽略。略。請(qǐng)留意請(qǐng)留意“下標(biāo)表達(dá)式不是常量表達(dá)式,即它的值下標(biāo)表達(dá)式不是常量表達(dá)式,即它的值不用在編譯時(shí)確定,可以在運(yùn)轉(zhuǎn)時(shí)確定。不用在編譯時(shí)確定,可以在運(yùn)轉(zhuǎn)時(shí)確定。 堆內(nèi)存的分配與釋放堆內(nèi)存的分配與釋放【例【例7.1】動(dòng)態(tài)數(shù)組的建立與撤銷】動(dòng)態(tài)數(shù)組的建立與

11、撤銷#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ù)組的元素個(gè)數(shù)n; /在運(yùn)轉(zhuǎn)時(shí)確定,可輸入在運(yùn)轉(zhuǎn)時(shí)確定,可輸入17pc=new charn; /懇求懇求17個(gè)字符可裝個(gè)字符可裝8個(gè)漢字和一個(gè)終了符的內(nèi)存空間個(gè)漢字和一個(gè)終了符的內(nèi)存空間strcpy(pc,堆內(nèi)存的動(dòng)態(tài)分配堆內(nèi)存的動(dòng)態(tài)分配);coutpcendl;delete pc;/釋放釋放pc所指向的所指向的n個(gè)字符的內(nèi)存空間個(gè)字符的內(nèi)存空間return ; 堆內(nèi)存的分配與釋放堆內(nèi)存的分配與釋放動(dòng)態(tài)分配數(shù)組有三個(gè)特點(diǎn):動(dòng)態(tài)分配數(shù)組有三個(gè)特點(diǎn):變量變量n在編譯

12、時(shí)沒(méi)有確定的值,而是在運(yùn)轉(zhuǎn)中輸入,按運(yùn)在編譯時(shí)沒(méi)有確定的值,而是在運(yùn)轉(zhuǎn)中輸入,按運(yùn)轉(zhuǎn)時(shí)所需分配堆空間,這一點(diǎn)是動(dòng)態(tài)分配的優(yōu)點(diǎn),可抑轉(zhuǎn)時(shí)所需分配堆空間,這一點(diǎn)是動(dòng)態(tài)分配的優(yōu)點(diǎn),可抑制數(shù)組制數(shù)組“大開(kāi)小用的弊端,在表、排序與查找中的算大開(kāi)小用的弊端,在表、排序與查找中的算法,假設(shè)用動(dòng)態(tài)數(shù)組,通用性更佳。法,假設(shè)用動(dòng)態(tài)數(shù)組,通用性更佳。delete pc是將是將n個(gè)個(gè)字符的空間釋放,而用字符的空間釋放,而用delete pc那么只釋放了一個(gè)字符那么只釋放了一個(gè)字符的空間;的空間;假設(shè)有一個(gè)假設(shè)有一個(gè)char *pc1,令,令pc1=p,同樣可用,同樣可用delete pc1來(lái)來(lái)釋放該空間。雖然釋放該

13、空間。雖然C+不對(duì)數(shù)組作邊境檢查,但在堆空不對(duì)數(shù)組作邊境檢查,但在堆空間分配時(shí),對(duì)數(shù)組分配空間大小是紀(jì)錄在案的。間分配時(shí),對(duì)數(shù)組分配空間大小是紀(jì)錄在案的。沒(méi)有初始化式?jīng)]有初始化式initializer,不可對(duì)數(shù)組初始化。,不可對(duì)數(shù)組初始化。 堆內(nèi)存的分配與釋放堆內(nèi)存的分配與釋放多維數(shù)組動(dòng)態(tài)分配:多維數(shù)組動(dòng)態(tài)分配: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ù)組的指針的指針cp=new float 15 30 20; /建立由建立由15個(gè)個(gè)30*20數(shù)組組成的

14、數(shù)組;數(shù)組組成的數(shù)組;留意留意cp等效于三維數(shù)組名,但沒(méi)有指出其邊境,即等效于三維數(shù)組名,但沒(méi)有指出其邊境,即最高維的元素?cái)?shù)量,就像指向字符的指針即等效一最高維的元素?cái)?shù)量,就像指向字符的指針即等效一個(gè)字符串個(gè)字符串,不要把指向字符的指針,說(shuō)成指向字符串不要把指向字符的指針,說(shuō)成指向字符串的指針。這與數(shù)組的嵌套定義相一致。的指針。這與數(shù)組的嵌套定義相一致。 堆內(nèi)存的分配與釋放堆內(nèi)存的分配與釋放比較:比較:float(*cp) 30 20; /三級(jí)指針;三級(jí)指針;float (*bp) 20; /二級(jí)指針;二級(jí)指針;cp=new float 1 20 30;bp=new float 30 20;兩

15、個(gè)數(shù)組都是由兩個(gè)數(shù)組都是由600個(gè)浮點(diǎn)數(shù)組成,前者是只需個(gè)浮點(diǎn)數(shù)組成,前者是只需一個(gè)元素的三維數(shù)組,每個(gè)元素為一個(gè)元素的三維數(shù)組,每個(gè)元素為30行行20列的二列的二維數(shù)組,而另一個(gè)是有維數(shù)組,而另一個(gè)是有30個(gè)元素的二維數(shù)組,每個(gè)元素的二維數(shù)組,每個(gè)元素為個(gè)元素為20個(gè)元素的一維數(shù)組。刪除這兩個(gè)動(dòng)態(tài)個(gè)元素的一維數(shù)組。刪除這兩個(gè)動(dòng)態(tài)數(shù)組可用下式:數(shù)組可用下式:delete cp; /刪除釋放三維數(shù)組;刪除釋放三維數(shù)組;delete bp; /刪除釋放二維數(shù)組;刪除釋放二維數(shù)組; 堆內(nèi)存的分配與釋放堆內(nèi)存的分配與釋放【例】【例】 動(dòng)態(tài)創(chuàng)建和刪除一個(gè)動(dòng)態(tài)創(chuàng)建和刪除一個(gè)m*n個(gè)元素的數(shù)組。采用指針數(shù)組

16、方式來(lái)個(gè)元素的數(shù)組。采用指針數(shù)組方式來(lái)完成二維數(shù)組的動(dòng)態(tài)創(chuàng)建。完成二維數(shù)組的動(dòng)態(tài)創(chuàng)建。const int m=4; /行數(shù)行數(shù)const int n=6; /列數(shù)列數(shù)先看二維數(shù)組的動(dòng)態(tài)創(chuàng)建:先看二維數(shù)組的動(dòng)態(tài)創(chuàng)建:void main() double *data; /假設(shè)改成假設(shè)改成 double (*data) n;后面如何改動(dòng)后面如何改動(dòng) data = new double*m; /設(shè)置行設(shè)置行 if (data ) = 0) cout Couuld not allocate. Bye .;return; for(int j=0;jm;j+) dataj = new doublen; /設(shè)

17、置列設(shè)置列 if (dataj = 0) cout Couuld not allocate. Bye .;return; for (int i=0;im;i+) for (int j=0;jn;j+) dataij=i*n+j;/初始化數(shù)組元素初始化數(shù)組元素 coutdataijendl; de_allocate(data); return; 堆內(nèi)存的分配與釋放堆內(nèi)存的分配與釋放再看二維數(shù)組的撤銷與內(nèi)存釋放:再看二維數(shù)組的撤銷與內(nèi)存釋放:void de_allocate(double *data) for (int i=0;im;i+) delete datai; /留意撤銷次序,先列后行,與

18、設(shè)置相反留意撤銷次序,先列后行,與設(shè)置相反 delete data; 指針運(yùn)用的幾個(gè)問(wèn)題:指針運(yùn)用的幾個(gè)問(wèn)題:動(dòng)態(tài)分配失敗。前往一個(gè)空指針動(dòng)態(tài)分配失敗。前往一個(gè)空指針NULL,表示發(fā)生,表示發(fā)生了異常,堆資源缺乏,分配失敗。了異常,堆資源缺乏,分配失敗。指針刪除與堆空間釋放。刪除一個(gè)指針指針刪除與堆空間釋放。刪除一個(gè)指針pdelete p;實(shí)踐實(shí)踐意思是刪除了意思是刪除了p所指的目的變量或?qū)ο蟮龋尫帕怂嫉亩芽账傅哪康淖兞炕驅(qū)ο蟮?,釋放了它所占的堆空間,而不是刪除本身,釋放堆空間后,成了空懸指針。間,而不是刪除本身,釋放堆空間后,成了空懸指針。 堆內(nèi)存的分配與釋放堆內(nèi)存的分配與釋放內(nèi)存走

19、漏內(nèi)存走漏memory leak和反復(fù)釋放。和反復(fù)釋放。new與與delete 是配對(duì)運(yùn)用的,是配對(duì)運(yùn)用的, delete只能釋放堆空間。假設(shè)只能釋放堆空間。假設(shè)new前往的指針值喪失,那么所分配的堆空間無(wú)法回收,前往的指針值喪失,那么所分配的堆空間無(wú)法回收,稱內(nèi)存走漏,同一空間反復(fù)釋放也是危險(xiǎn)的,由于該空間稱內(nèi)存走漏,同一空間反復(fù)釋放也是危險(xiǎn)的,由于該空間能夠已另分配,所以必需妥善保管能夠已另分配,所以必需妥善保管new前往的指針,以保前往的指針,以保證不發(fā)生內(nèi)存走漏,也必需保證不會(huì)反復(fù)釋放堆內(nèi)存空間。證不發(fā)生內(nèi)存走漏,也必需保證不會(huì)反復(fù)釋放堆內(nèi)存空間。動(dòng)態(tài)分配的變量或?qū)ο蟮纳凇o(wú)名對(duì)象

20、的生命期動(dòng)態(tài)分配的變量或?qū)ο蟮纳凇o(wú)名對(duì)象的生命期并不依賴于建立它的作用域,比如在函數(shù)中建立的動(dòng)態(tài)對(duì)并不依賴于建立它的作用域,比如在函數(shù)中建立的動(dòng)態(tài)對(duì)象在函數(shù)前往后仍可運(yùn)用。我們也稱堆空間為自在空間象在函數(shù)前往后仍可運(yùn)用。我們也稱堆空間為自在空間free store就是這個(gè)緣由。但必需記住釋放該對(duì)象所就是這個(gè)緣由。但必需記住釋放該對(duì)象所占堆空間,并只能釋放一次,在函數(shù)內(nèi)建立,而在函數(shù)外占堆空間,并只能釋放一次,在函數(shù)內(nèi)建立,而在函數(shù)外釋放是一件很容易失控的事,往往會(huì)出錯(cuò)。釋放是一件很容易失控的事,往往會(huì)出錯(cuò)。 堆對(duì)象與構(gòu)造函數(shù)堆對(duì)象與構(gòu)造函數(shù) 經(jīng)過(guò)經(jīng)過(guò)new建立的對(duì)象要調(diào)用構(gòu)造函數(shù),經(jīng)過(guò)建

21、立的對(duì)象要調(diào)用構(gòu)造函數(shù),經(jīng)過(guò)delete刪除對(duì)象刪除對(duì)象也要調(diào)用析構(gòu)函數(shù)。也要調(diào)用析構(gòu)函數(shù)。CGoods *pc;pc=new CGoods; /分配堆空間,并構(gòu)造一個(gè)無(wú)名的分配堆空間,并構(gòu)造一個(gè)無(wú)名的CGoods對(duì)象;對(duì)象;.delete pc; /先析構(gòu),然后將內(nèi)存空間前往給堆;先析構(gòu),然后將內(nèi)存空間前往給堆; 堆對(duì)象的生命期并不依賴于建立它的作用域,所以除非程序堆對(duì)象的生命期并不依賴于建立它的作用域,所以除非程序終了,堆對(duì)象無(wú)名對(duì)象的生命期不會(huì)到期,并且需求顯式終了,堆對(duì)象無(wú)名對(duì)象的生命期不會(huì)到期,并且需求顯式地用地用delete語(yǔ)句析構(gòu)堆對(duì)象,上面的堆對(duì)象在執(zhí)行語(yǔ)句析構(gòu)堆對(duì)象,上面的堆

22、對(duì)象在執(zhí)行delete語(yǔ)句時(shí),語(yǔ)句時(shí),C+自動(dòng)調(diào)用其析構(gòu)函數(shù)。自動(dòng)調(diào)用其析構(gòu)函數(shù)。正由于構(gòu)造函數(shù)可以有參數(shù),所以正由于構(gòu)造函數(shù)可以有參數(shù),所以new后面類后面類class類型也可類型也可以有參數(shù)。這些參數(shù)即構(gòu)造函數(shù)的參數(shù)。但對(duì)創(chuàng)建數(shù)組,那么以有參數(shù)。這些參數(shù)即構(gòu)造函數(shù)的參數(shù)。但對(duì)創(chuàng)建數(shù)組,那么無(wú)參數(shù),并只調(diào)用缺省的構(gòu)造函數(shù)。見(jiàn)下例類闡明:無(wú)參數(shù),并只調(diào)用缺省的構(gòu)造函數(shù)。見(jiàn)下例類闡明:堆對(duì)象與構(gòu)造函數(shù)堆對(duì)象與構(gòu)造函數(shù)class CGoods char Name21; int Amount; float Price; float Total_value;public: CGoods(); /缺省構(gòu)

23、造函數(shù)。缺省構(gòu)造函數(shù)。 /因已有構(gòu)造函數(shù),系統(tǒng)不會(huì)自動(dòng)生成,必需顯式闡明。因已有構(gòu)造函數(shù),系統(tǒng)不會(huì)自動(dòng)生成,必需顯式闡明。 CGoods(char* name,int amount ,float price) strcpy(Name,name); Amount=amount; Price=price; Total_value=price*amount; ;堆對(duì)象與構(gòu)造函數(shù)堆對(duì)象與構(gòu)造函數(shù)下面留意如何運(yùn)用:下面留意如何運(yùn)用:void main() int n; CGoods *pc,*pc1,*pc2; pc=new CGoods(“夏利夏利2000,10,118000); /調(diào)用三參數(shù)構(gòu)造函數(shù)

24、調(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ù)組,不能初始化,調(diào)用動(dòng)態(tài)建立數(shù)組,不能初始化,調(diào)用n次缺省構(gòu)造函數(shù)次缺省構(gòu)造函數(shù) delete pc; delete pc1; delete pc2;堆對(duì)象與構(gòu)造函數(shù)堆對(duì)象與構(gòu)造函數(shù)這里再次強(qiáng)調(diào):由堆區(qū)創(chuàng)建對(duì)象數(shù)這里再次強(qiáng)調(diào):由堆區(qū)創(chuàng)建對(duì)象數(shù)組,只能調(diào)用缺省的構(gòu)造函數(shù),不能調(diào)組,只能調(diào)用缺省的構(gòu)造函數(shù),不能調(diào)用其他任何構(gòu)造函數(shù)。假設(shè)沒(méi)有缺省的用其他任何構(gòu)造函數(shù)。假設(shè)沒(méi)有缺省的構(gòu)造函數(shù),那么不能創(chuàng)建堆區(qū)的

25、對(duì)象數(shù)構(gòu)造函數(shù),那么不能創(chuàng)建堆區(qū)的對(duì)象數(shù)組。組。淺拷貝與深拷貝淺拷貝與深拷貝 缺省拷貝構(gòu)造函數(shù),可用一個(gè)類對(duì)象初始化另一個(gè)缺省拷貝構(gòu)造函數(shù),可用一個(gè)類對(duì)象初始化另一個(gè)類對(duì)象,稱為缺省的按成員拷貝,而不是對(duì)整個(gè)類對(duì)象類對(duì)象,稱為缺省的按成員拷貝,而不是對(duì)整個(gè)類對(duì)象的按位拷貝。這稱為淺拷貝。的按位拷貝。這稱為淺拷貝。 P堆對(duì)堆對(duì)象象堆對(duì)堆對(duì)象象PP 圖圖1 淺拷貝淺拷貝 拷貝前拷貝后拷貝后 淺拷貝與深拷貝淺拷貝與深拷貝假設(shè)類中有一個(gè)數(shù)據(jù)成員為指針,假設(shè)類中有一個(gè)數(shù)據(jù)成員為指針,該類的一個(gè)對(duì)象該類的一個(gè)對(duì)象obj1中的這個(gè)指針中的這個(gè)指針p,指向了動(dòng)態(tài)分配的一個(gè)堆對(duì)象,參指向了動(dòng)態(tài)分配的一個(gè)堆對(duì)象,

26、參見(jiàn)圖見(jiàn)圖1拷貝前,假設(shè)用拷貝前,假設(shè)用obj1按成員按成員拷貝了一個(gè)對(duì)象拷貝了一個(gè)對(duì)象obj2,這時(shí),這時(shí)obj2.p也也指向同一個(gè)堆對(duì)象。當(dāng)析構(gòu)時(shí),如用指向同一個(gè)堆對(duì)象。當(dāng)析構(gòu)時(shí),如用缺省的析構(gòu)函數(shù),那么動(dòng)態(tài)分配的堆缺省的析構(gòu)函數(shù),那么動(dòng)態(tài)分配的堆對(duì)象不能回收。假設(shè)在析構(gòu)函數(shù)中有對(duì)象不能回收。假設(shè)在析構(gòu)函數(shù)中有“delete p;語(yǔ)句,那么假設(shè)先析構(gòu)函語(yǔ)句,那么假設(shè)先析構(gòu)函數(shù)數(shù)obj1時(shí),堆對(duì)象曾經(jīng)釋放,以后再時(shí),堆對(duì)象曾經(jīng)釋放,以后再析構(gòu)析構(gòu)obj2時(shí)出現(xiàn)了二次釋放的問(wèn)題。時(shí)出現(xiàn)了二次釋放的問(wèn)題。這時(shí)就要重新定義拷貝的構(gòu)造函數(shù),這時(shí)就要重新定義拷貝的構(gòu)造函數(shù),給每個(gè)對(duì)象獨(dú)立分配一個(gè)堆對(duì)象

27、,稱給每個(gè)對(duì)象獨(dú)立分配一個(gè)堆對(duì)象,稱深拷貝。這時(shí)先拷貝對(duì)象主體,再為深拷貝。這時(shí)先拷貝對(duì)象主體,再為obj2分配一個(gè)堆對(duì)象,最后用分配一個(gè)堆對(duì)象,最后用obj1的的堆對(duì)象拷貝堆對(duì)象拷貝obj2的堆對(duì)象。的堆對(duì)象。 堆對(duì)堆對(duì)象象PP堆對(duì)堆對(duì)象象 圖圖2 深拷貝深拷貝 淺拷貝與深拷貝淺拷貝與深拷貝例例7.3定義拷貝定義拷貝copy structor和拷貝賦值操作符和拷貝賦值操作符copy Assignment Operator實(shí)現(xiàn)深拷貝。實(shí)現(xiàn)深拷貝。 學(xué)生類定義:學(xué)生類定義:class studentchar *pName; /指針成員指針成員public:student();student(char *pname);student(student &s); /拷貝構(gòu)造函數(shù)拷貝構(gòu)造函數(shù)student();student & operator=(student &s); /拷貝賦值操作符拷貝賦值操作符;缺省構(gòu)造函數(shù):缺省構(gòu)造函數(shù):student:student()coutConstru

溫馨提示

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