版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、5.7 多級指針與多維數(shù)組多級指針與多維數(shù)組 (選讀)(選讀)多級指針的概念:多級指針的概念:多級指針可對應(yīng)于多維數(shù)組,這種指針變量中存的是另多級指針可對應(yīng)于多維數(shù)組,這種指針變量中存的是另一個指針變量的地址,其說明如下:一個指針變量的地址,其說明如下:int val=10;int *ptr=&val;int *pptr=&ptr;int *ppptr=&pptr; /是多少級指針就有多少是多少級指針就有多少*號號這里這里val值為值為10,*ptr值也為值也為10,*pptr的值和的值和*ppptr的值均為的值均為10。(。(注意:注意:這段文字中的這段文字中的*號是
2、運號是運算符,稱算符,稱間接引用運算符間接引用運算符。與定義中的。與定義中的*號意義不同,號意義不同,定義中的定義中的是指針說明符。)是指針說明符。)【例【例5.13】多級指針多級指針int main()int val=66;int *pval = &val;int *ppval = &pval; coutval=valn*ppval= *ppvaln; *ppval=18;coutval=valn*ppval=“ *ppvalendl;return 0;程序中程序中ppval稱為多級指針,稱為多級指針,val、pval和和ppval之間的關(guān)之間的關(guān)系參見圖系參見圖5.7。【例
3、【例5.13】多級指針(選讀)】多級指針(選讀)變量變量ppval變量變量pval變量變量val圖圖5.7 5.7 多級指針多級指針5.7 多級指針與多維數(shù)組多級指針與多維數(shù)組 (選讀)(選讀)指針兩要素:指針兩要素: 指向數(shù)組(元素)類型指向數(shù)組(元素)類型的的指針指針,與一維數(shù)組名是等,與一維數(shù)組名是等效的:效的:int a10, *pa =a;則寫則寫pa0 ,就是,就是a0;*pa,即,即a0;*(pa+1) 和和pa1 ,都代表,都代表a1。 指針有兩要素:地址和所指向目標(biāo)的數(shù)據(jù)類型。指針有兩要素:地址和所指向目標(biāo)的數(shù)據(jù)類型。a 與與pa 兩者都是一樣的,所以兩者都是一樣的,所以pa
4、 可以替代可以替代a。5.7 多級指針與多維數(shù)組多級指針與多維數(shù)組 (選讀)(選讀)指向一維數(shù)組的指針的定義如下:指向一維數(shù)組的指針的定義如下:數(shù)據(jù)類型數(shù)據(jù)類型 (* 指針變量名指針變量名)n;這里數(shù)組元素的個數(shù)這里數(shù)組元素的個數(shù)n不可省略。因是指向指針的指針,稱二不可省略。因是指向指針的指針,稱二級指針。級指針。 二維數(shù)組與指針:二維數(shù)組與指針: 二維數(shù)組是數(shù)組元素為一維數(shù)組的數(shù)組,所以等效的指二維數(shù)組是數(shù)組元素為一維數(shù)組的數(shù)組,所以等效的指針類型應(yīng)該是針類型應(yīng)該是指向一維數(shù)組的指針類型指向一維數(shù)組的指針類型。如有:。如有:int x2d34=1,2,3,4,5,6,7,8,9,10,11,
5、12;int (*pt)4=x2d;則指針則指針pt 和和x2d 是等效的。它們表示的首地址一樣,所指目是等效的。它們表示的首地址一樣,所指目標(biāo)類型也一樣,標(biāo)類型也一樣,pt 可以代替可以代替x2d,就象,就象pa代替代替a一樣。一樣。 指向行方向指向行方向x2d00 x2d12x2d02x2d03x2d10 x2d11x2d20 x2d01x2d23x2d21x2d0 x2d+1(或或pt+1)x2d22x2d1x2d2x2d13x2d(或(或pt)指向列方向指向列方向x2d+2(或或pt+2)圖圖5.8 二維數(shù)組剖析二維數(shù)組剖析x2d指向的是一個由指針組成的數(shù)組,包括指向的是一個由指針組成
6、的數(shù)組,包括x2d0,x2d1和和x2d2 。由此可見,存儲二維數(shù)組還必須保存一些訪問數(shù)組。由此可見,存儲二維數(shù)組還必須保存一些訪問數(shù)組元素的輔助信息,如:元素的輔助信息,如:x2d0,x2d1和和x2d2。 在這里在這里x2d即即&x2d0,即,即x2d中放的是中放的是第第0行行x2d0的地的地址址,其所指,其所指目標(biāo)是由目標(biāo)是由4個整型數(shù)組成的一維數(shù)組個整型數(shù)組成的一維數(shù)組,占內(nèi)存,占內(nèi)存16個個字節(jié)。字節(jié)。pt等效等效x2d,*pt即即x2d0。二維數(shù)組剖析:二維數(shù)組剖析:表示形式表示形式含義含義X2d, & x2d0二維數(shù)組名表示指向第二維數(shù)組名表示指向第0行的指針行的
7、指針x2d0 ,*(x2d+0),* x2d, & x2d00 指向二維數(shù)組第指向二維數(shù)組第0行第行第0列元素的指針列元素的指針x2d+i, & x2di指向二維數(shù)組第指向二維數(shù)組第i行的指針行的指針x2di, *( x2d+i)指向二維數(shù)組第指向二維數(shù)組第i行第行第0列元素的指針列元素的指針x2di+j,*( x2d+i)+j, & x2dij指向二維數(shù)組第指向二維數(shù)組第i行第行第j列元素的指針列元素的指針*(x2di+j),*(*( x2d+i)+j), x2dij二維數(shù)組第二維數(shù)組第i行第行第j列元素的值列元素的值表表5.1 數(shù)組與指針的等價關(guān)系數(shù)組與指針的等價關(guān)
8、系指向行方向指向行方向x2d00 x2d12x2d02x2d03x2d10 x2d11x2d20 x2d01x2d23x2d21x2d0 x2d+1(或或pt+1)x2d22x2d1x2d2x2d13x2d(或(或pt)指向列方向指向列方向x2d+2(或或pt+2)注意:上下兩圖表對比注意:上下兩圖表對比5.7 多級指針與多維數(shù)組多級指針與多維數(shù)組 (選讀)(選讀)【例【例5.14】用指向二維數(shù)組基本元素的指針變用指向二維數(shù)組基本元素的指針變量,和用指向組成二維數(shù)組的一維數(shù)組的指針量,和用指向組成二維數(shù)組的一維數(shù)組的指針變量輸出二維數(shù)組全部基本元素。變量輸出二維數(shù)組全部基本元素。 用用指向數(shù)組
9、元素的指針指向數(shù)組元素的指針把數(shù)組傳遞到函數(shù)里,把數(shù)組傳遞到函數(shù)里,同時傳遞同時傳遞行列信息行列信息,就可以,就可以實現(xiàn)通用性實現(xiàn)通用性?!纠纠?.14】用指針變量輸出二維數(shù)組(選讀)】用指針變量輸出二維數(shù)組(選讀)int main( ) int a36=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18; int * ptr,i,j; ptr=&a00 ; /或或 ptr = *a; 而不能而不能ptr = a; for(i=0;i18;i+)cout*(ptr+i)t;if(i%6=5) coutendl; coutendl; int (*
10、ptr1)6; /注意注意 ptr1是指向包含是指向包含6個整型元素的一維數(shù)組的指針個整型元素的一維數(shù)組的指針 ptr1=a; for(i=0;i3;i+) for(j=0;j6;j+) cout*(*(ptr1+i)+j)t;coutendl; return 0;指針數(shù)組指針數(shù)組n數(shù)組的元素是指針型數(shù)組的元素是指針型例:例:Point *pa2; 由由pa0,pa1兩個指針組成兩個指針組成利用指針數(shù)組存放單位矩陣?yán)弥羔様?shù)組存放單位矩陣#include using namespace std;void main()int line1=1,0,0; /聲明數(shù)組,矩陣的第一行聲明數(shù)組,矩陣的第一
11、行int line2=0,1,0; /聲明數(shù)組,矩陣的第二行聲明數(shù)組,矩陣的第二行int line3=0,0,1; /聲明數(shù)組,矩陣的第三行聲明數(shù)組,矩陣的第三行int *p_line3;/聲明整型指針數(shù)組聲明整型指針數(shù)組p_line0=line1;/初始化指針數(shù)組元素初始化指針數(shù)組元素p_line1=line2;p_line2=line3; coutMatrix test:endl; /輸出單位矩陣輸出單位矩陣for(int i=0;i3;i+)/對指針數(shù)組元素循環(huán)對指針數(shù)組元素循環(huán) for(int j=0;j3;j+)/對矩陣每一行循環(huán)對矩陣每一行循環(huán) coutp_lineij ; cou
12、t成員名成員名ptr-getx() 相當(dāng)于相當(dāng)于 (*ptr).getx();對象指針應(yīng)用舉例對象指針應(yīng)用舉例int main() Point A(5,10); Point *ptr; ptr=&A; int x; x=ptr-GetX(); coutxendl; return 0;void類型指針的使用類型指針的使用void vobject; /錯,不能聲明錯,不能聲明void類型的變量類型的變量void *pv; /對,可以聲明對,可以聲明void類型的指針類型的指針int *pint; int i;void main() /void類型的函數(shù)沒有返回值類型的函數(shù)沒有返回值pv =
13、 &i; /void類型指針指向整型變量類型指針指向整型變量 / void指針賦值給指針賦值給int指針需要類型強制轉(zhuǎn)換指針需要類型強制轉(zhuǎn)換: pint = (int *)pv; 第七章第七章 動態(tài)內(nèi)存分配動態(tài)內(nèi)存分配7.17.1自由存儲區(qū)內(nèi)存分配自由存儲區(qū)內(nèi)存分配 7.1.1自由存儲區(qū)自由存儲區(qū)內(nèi)存內(nèi)存的分配與釋放的分配與釋放 7.1.2自由存儲區(qū)自由存儲區(qū)對象對象與構(gòu)造函數(shù)與構(gòu)造函數(shù) 7.1.3 淺復(fù)制與深復(fù)制淺復(fù)制與深復(fù)制 靜態(tài)存儲分配:靜態(tài)存儲分配:無論全局或局部變量無論全局或局部變量( (對象對象) ),編,編譯器在譯器在編譯時編譯時都可以根據(jù)該變量都可以根據(jù)該變量( (對象
14、對象) )的類型知道所需內(nèi)存空間的類型知道所需內(nèi)存空間的大小,從而系統(tǒng)在適當(dāng)?shù)臅r候的大小,從而系統(tǒng)在適當(dāng)?shù)臅r候為它們分配確定的存儲空間。尤為它們分配確定的存儲空間。尤其是數(shù)組。其是數(shù)組。動態(tài)存儲分配:動態(tài)存儲分配:有些操作對象只有在程序有些操作對象只有在程序運行時運行時才能確定,這樣編譯器在編譯時才能確定,這樣編譯器在編譯時就無法為他們預(yù)定存儲空間,只就無法為他們預(yù)定存儲空間,只能在程序運行時,系統(tǒng)根據(jù)運行能在程序運行時,系統(tǒng)根據(jù)運行時的要求進(jìn)行內(nèi)存分配,稱為動時的要求進(jìn)行內(nèi)存分配,稱為動態(tài)存儲分配。動態(tài)分配都在態(tài)存儲分配。動態(tài)分配都在自由自由存儲區(qū)存儲區(qū)中進(jìn)行。中進(jìn)行。動態(tài)申請內(nèi)存操作符動態(tài)
15、申請內(nèi)存操作符 new格式格式: :new new 類型名類型名T T(初值列表)(初值列表)功能:功能:在程序執(zhí)行期間,申請用于存放在程序執(zhí)行期間,申請用于存放T類型對象的內(nèi)存空類型對象的內(nèi)存空間,并依初值列表賦以初值。間,并依初值列表賦以初值。結(jié)果值結(jié)果值:成功:成功:T類型的指針,指向新分配的內(nèi)存。失敗:類型的指針,指向新分配的內(nèi)存。失?。?(NULL)例:例: int *p1=new int; int *p2=new int(90); int *p3=new int90;釋放內(nèi)存操作符釋放內(nèi)存操作符delete格式格式: :delete delete 指針指針P P功能:功能:釋放指針
16、釋放指針P所指向的內(nèi)存。所指向的內(nèi)存。P必須是必須是new操作的操作的返回值。返回值。delete p1;delete p3; 7.1.17.1.1自由存儲區(qū)自由存儲區(qū)內(nèi)存的分配與釋放內(nèi)存的分配與釋放自由存儲區(qū)自由存儲區(qū)i演示:演示:用初始化式用初始化式(initializer)(initializer)來顯式初始化來顯式初始化 int *pi=new int(0);當(dāng)當(dāng)pipi生命周期結(jié)束時,生命周期結(jié)束時,必須釋放必須釋放pipi所指向的目標(biāo):所指向的目標(biāo): delete pi;注意這時釋放了注意這時釋放了pipi所指的目標(biāo)的內(nèi)存空間,也就是撤銷了所指的目標(biāo)的內(nèi)存空間,也就是撤銷了該目標(biāo),
17、稱動態(tài)內(nèi)存釋放(該目標(biāo),稱動態(tài)內(nèi)存釋放(dynamic memory dynamic memory deallocationdeallocation),但),但指針指針pipi本身并沒有撤銷本身并沒有撤銷,該指針?biāo)?,該指針?biāo)純?nèi)存空間并未釋放。內(nèi)存空間并未釋放。 7.1.17.1.1自由存儲區(qū)自由存儲區(qū)內(nèi)存的分配與釋放內(nèi)存的分配與釋放數(shù)組動態(tài)分配格式:數(shù)組動態(tài)分配格式:指針變量名指針變量名=new 類型名類型名下標(biāo)表達(dá)式下標(biāo)表達(dá)式;delete 指向該數(shù)組的指針變量名指向該數(shù)組的指針變量名;說明:說明:兩式中的兩式中的方括號方括號必須配對使用。必須配對使用。如果如果delete語句中少了方括
18、號,因編譯器認(rèn)為該指針是指語句中少了方括號,因編譯器認(rèn)為該指針是指向數(shù)組第一個元素的指針,會產(chǎn)生向數(shù)組第一個元素的指針,會產(chǎn)生回收不徹底回收不徹底的問題(的問題(只只回收了第一個元素所占空間回收了第一個元素所占空間),),加了方括號后就轉(zhuǎn)化為指加了方括號后就轉(zhuǎn)化為指向數(shù)組的指針,回收整個數(shù)組向數(shù)組的指針,回收整個數(shù)組。 delete 的方括號中的方括號中不需要不需要填填數(shù)組元素數(shù)數(shù)組元素數(shù),系統(tǒng)自知。,系統(tǒng)自知。即使寫了,編譯器也忽略。即使寫了,編譯器也忽略。 請注意請注意“下標(biāo)表達(dá)式下標(biāo)表達(dá)式”不是常量表達(dá)式不是常量表達(dá)式,即它,即它的值不必在編譯時確定,的值不必在編譯時確定,可以在運行時確
19、定可以在運行時確定。7.1.17.1.1自由存儲區(qū)自由存儲區(qū)內(nèi)存的分配與釋放內(nèi)存的分配與釋放動態(tài)分配數(shù)組與動態(tài)分配數(shù)組與標(biāo)準(zhǔn)字符串類標(biāo)準(zhǔn)字符串類: 標(biāo)準(zhǔn)字符串類標(biāo)準(zhǔn)字符串類string就是采用動態(tài)建立數(shù)組的方式解決就是采用動態(tài)建立數(shù)組的方式解決數(shù)組溢出的問題的,例數(shù)組溢出的問題的,例7.1所做的動態(tài)內(nèi)存分配與釋放,所做的動態(tài)內(nèi)存分配與釋放,在在string類對象中都是自動完成的,在程序中不需要也不類對象中都是自動完成的,在程序中不需要也不允許再顯式地為允許再顯式地為string進(jìn)行動態(tài)內(nèi)存的分配與釋放。進(jìn)行動態(tài)內(nèi)存的分配與釋放。【例【例7.1】動態(tài)數(shù)組的建立與撤銷】動態(tài)數(shù)組的建立與撤銷7.1.
20、17.1.1自由存儲區(qū)自由存儲區(qū)內(nèi)存的分配與釋放內(nèi)存的分配與釋放【例【例7.17.1】【例【例7.1】動態(tài)數(shù)組的建立與撤銷】動態(tài)數(shù)組的建立與撤銷#include #include using namespace std;int main()int n;char *pc;cout請輸入動態(tài)數(shù)組的元素個數(shù)請輸入動態(tài)數(shù)組的元素個數(shù)n; /在運行時確定,可輸入在運行時確定,可輸入25pc=new charn;strcpy(pc, 自由存儲區(qū)內(nèi)存的動態(tài)分配自由存儲區(qū)內(nèi)存的動態(tài)分配);coutpcendl;delete pc;/釋放釋放pc所指向的所指向的n個字符的內(nèi)存空間個字符的內(nèi)存空間return 0
21、;#include using namespace std;void main() int n;cinn;int *p=new intn;int num;cinnum;int j=0;while (num0) pj+=num%2;num/=2;for (int i=j-1;i=0;i-)coutpi; delete p;7.1.17.1.1自由存儲區(qū)自由存儲區(qū)內(nèi)存的分配與釋放內(nèi)存的分配與釋放動態(tài)分配數(shù)組的特點:動態(tài)分配數(shù)組的特點:1. 變量變量n在編譯時沒有確定的值,而是在運行中輸入,在編譯時沒有確定的值,而是在運行中輸入,按運行按運行時所需分配空間時所需分配空間,這一點是動態(tài)分配的優(yōu)點,可克
22、服數(shù)組,這一點是動態(tài)分配的優(yōu)點,可克服數(shù)組“大開小用大開小用”的弊端,在表、排序與查找中的算法,若用的弊端,在表、排序與查找中的算法,若用動態(tài)數(shù)組,通用性更佳。動態(tài)數(shù)組,通用性更佳。delete pc是將是將n個字符的空間個字符的空間釋放,而用釋放,而用delete pc則只釋放了一個字符的空間;則只釋放了一個字符的空間;2. 如果有如果有char *pc1,令,令pc1=pc,同樣可用,同樣可用delete pc1 來釋放該空間。盡管來釋放該空間。盡管C+不對數(shù)組作邊界檢查,但不對數(shù)組作邊界檢查,但在自由在自由 存儲區(qū)存儲區(qū) 空間分配時,對數(shù)組分配空間大小是紀(jì)錄在案的空間分配時,對數(shù)組分配空
23、間大小是紀(jì)錄在案的。3. 沒有初始化式(沒有初始化式(initializer),),不可對數(shù)組初始化不可對數(shù)組初始化。 7.1.17.1.1自由存儲區(qū)自由存儲區(qū)內(nèi)存的分配與釋放內(nèi)存的分配與釋放(選讀)(選讀)【例【例7.2】 動態(tài)創(chuàng)建和刪除一個動態(tài)創(chuàng)建和刪除一個m*n個元素的數(shù)組個元素的數(shù)組7.1.17.1.1自由存儲區(qū)自由存儲區(qū)內(nèi)存的分配與釋放內(nèi)存的分配與釋放【例【例7.27.2】 【例【例7.2】 動態(tài)創(chuàng)建和刪除一個動態(tài)創(chuàng)建和刪除一個m*n個元素的數(shù)組。采用個元素的數(shù)組。采用指針數(shù)指針數(shù)組方式組方式來完成二維數(shù)組的動態(tài)創(chuàng)建。來完成二維數(shù)組的動態(tài)創(chuàng)建。(選讀選讀)int m=4,n=6; /
24、行數(shù)與列數(shù)行數(shù)與列數(shù)二維數(shù)組的動態(tài)創(chuàng)建:二維數(shù)組的動態(tài)創(chuàng)建:int main() double *data; int i,j; data = new double*m; /建立指向組成二維數(shù)組各行的指針數(shù)組建立指向組成二維數(shù)組各行的指針數(shù)組 if (data ) = 0) cout Could not allocate. Bye .; return -1; for(j=0;jm;j+) dataj = new doublen; /建立各行建立各行 if (dataj = 0) cout Could not allocate. Bye .; return -1; 7.1.17.1.1自由存儲區(qū)自
25、由存儲區(qū)內(nèi)存的分配與釋放內(nèi)存的分配與釋放【例【例7.27.2】 for (i=0;im;i+) for (j=0;jn;j+) dataij=i*n+j; /數(shù)組元素賦值數(shù)組元素賦值 display(data);/略略 de_allocate(data); return 0; 二維數(shù)組的撤銷與內(nèi)存釋放:二維數(shù)組的撤銷與內(nèi)存釋放:void de_allocate(double *data) int i; for (i=0;im;i+) delete datai; /注意撤銷次序,與設(shè)置相反注意撤銷次序,與設(shè)置相反 delete data; 7.1.17.1.1自由存儲區(qū)自由存儲區(qū)的分配與釋放的分
26、配與釋放指針使用的要點:指針使用的要點:1. 動態(tài)分配失敗動態(tài)分配失敗。返回一個空指針(。返回一個空指針(NULL),表示發(fā)生了異),表示發(fā)生了異常,堆資源不足,分配失敗。常,堆資源不足,分配失敗。2. 指針刪除與自由存儲區(qū)空間釋放指針刪除與自由存儲區(qū)空間釋放。刪除一個指針。刪除一個指針p(delete p;)實際意思是刪除了)實際意思是刪除了p所指的目標(biāo)(變量或?qū)ο蟮龋屗傅哪繕?biāo)(變量或?qū)ο蟮龋尫帕怂嫉淖杂纱鎯^(qū)空間,而不是刪除本身,釋放自放了它所占的自由存儲區(qū)空間,而不是刪除本身,釋放自由存儲區(qū)空間后,成了空懸指針??諔抑羔樖浅绦蝈e誤的由存儲區(qū)空間后,成了空懸指針??諔抑羔樖浅?/p>
27、序錯誤的一個根源)。建議這時將置空(一個根源)。建議這時將置空(NULL)。)。3. new()和和delete()是可以重載的是可以重載的,它們都是類的靜態(tài)成員函,它們都是類的靜態(tài)成員函數(shù)。程序員無需顯式聲明它為靜態(tài)的,系統(tǒng)自動定義為靜態(tài)數(shù)。程序員無需顯式聲明它為靜態(tài)的,系統(tǒng)自動定義為靜態(tài)的。本教材不討論的。本教材不討論new()和和delete()的重載。未重載時,調(diào)用的重載。未重載時,調(diào)用全局庫操作符全局庫操作符new()。7.1.17.1.1自由存儲區(qū)自由存儲區(qū)內(nèi)存的分配與釋放內(nèi)存的分配與釋放4內(nèi)存泄漏(內(nèi)存泄漏(memory leak)和重復(fù)釋放)和重復(fù)釋放。new與與delete
28、是配對使用的,是配對使用的, delete只能釋放只能釋放自由存儲區(qū)自由存儲區(qū)空間??臻g。如果如果new返回的指針值丟失,則所分配的返回的指針值丟失,則所分配的自由存儲區(qū)自由存儲區(qū)空間空間無法回收,稱內(nèi)存泄漏,同一空間重復(fù)釋放也是危險的,無法回收,稱內(nèi)存泄漏,同一空間重復(fù)釋放也是危險的,因為因為該空間可能已另分配該空間可能已另分配,所以必須妥善保存,所以必須妥善保存new返回的返回的指針,以保證不發(fā)生內(nèi)存泄漏,也必須保證不會重復(fù)釋放指針,以保證不發(fā)生內(nèi)存泄漏,也必須保證不會重復(fù)釋放自由存儲區(qū)自由存儲區(qū)內(nèi)存空間。內(nèi)存空間。5動態(tài)分配的變量或?qū)ο蟮纳趧討B(tài)分配的變量或?qū)ο蟮纳?。無名對象的生命
29、期無名對象的生命期并不依賴于建立它的作用域,比如在函數(shù)中建立的動態(tài)對并不依賴于建立它的作用域,比如在函數(shù)中建立的動態(tài)對象在函數(shù)返回后仍可使用象在函數(shù)返回后仍可使用。但必須記住釋放該對象所占自。但必須記住釋放該對象所占自由存儲區(qū)空間,并只能釋放一次,在函數(shù)內(nèi)建立,而在函由存儲區(qū)空間,并只能釋放一次,在函數(shù)內(nèi)建立,而在函數(shù)外釋放是一件很容易數(shù)外釋放是一件很容易失控失控的事,往往會出錯。的事,往往會出錯。 7.1.27.1.2自由存儲區(qū)自由存儲區(qū)對象與構(gòu)造函數(shù)對象與構(gòu)造函數(shù) 類對象動態(tài)建立與刪除過程:類對象動態(tài)建立與刪除過程:通過通過new建立的對象要調(diào)用構(gòu)造函數(shù),通過建立的對象要調(diào)用構(gòu)造函數(shù),通過
30、delete刪除對刪除對象也要調(diào)用析構(gòu)函數(shù)。象也要調(diào)用析構(gòu)函數(shù)。CGoods *pc;pc=new CGoods; /分配自由存儲區(qū)空間,并構(gòu)造一個無名的分配自由存儲區(qū)空間,并構(gòu)造一個無名的CGoods對象;對象;.delete pc; /先析構(gòu),然后將內(nèi)存空間返回給自由存儲區(qū);先析構(gòu),然后將內(nèi)存空間返回給自由存儲區(qū);自由存儲區(qū)自由存儲區(qū)對象的生命期并不依賴于建立它的作用域,所以對象的生命期并不依賴于建立它的作用域,所以除非程序結(jié)束,除非程序結(jié)束,自由存儲區(qū)自由存儲區(qū)對象(無名對象)的生命期不會對象(無名對象)的生命期不會到期,并且需要顯式地用到期,并且需要顯式地用delete語句析構(gòu)該類對象
31、,上例執(zhí)語句析構(gòu)該類對象,上例執(zhí)行行delete語句時,語句時,C+自動調(diào)用商品類的析構(gòu)函數(shù)。自動調(diào)用商品類的析構(gòu)函數(shù)。7.1.27.1.2自由存儲區(qū)自由存儲區(qū)對象與構(gòu)造函數(shù)對象與構(gòu)造函數(shù)由自由存儲區(qū)創(chuàng)建對象數(shù)組,只能調(diào)用默認(rèn)由自由存儲區(qū)創(chuàng)建對象數(shù)組,只能調(diào)用默認(rèn)的構(gòu)造函數(shù),不能調(diào)用其他任何構(gòu)造函數(shù)。如果的構(gòu)造函數(shù),不能調(diào)用其他任何構(gòu)造函數(shù)。如果沒有默認(rèn)的構(gòu)造函數(shù),則不能創(chuàng)建對象數(shù)組。沒有默認(rèn)的構(gòu)造函數(shù),則不能創(chuàng)建對象數(shù)組。類對象初始化:類對象初始化:new后面類(后面類(class)類型可以有參數(shù)。這些參數(shù)即構(gòu)造函數(shù)的)類型可以有參數(shù)。這些參數(shù)即構(gòu)造函數(shù)的參數(shù)。但對參數(shù)。但對創(chuàng)建數(shù)組創(chuàng)建數(shù)組
32、,則無參數(shù),則無參數(shù),只能調(diào)用默認(rèn)的構(gòu)造函數(shù)只能調(diào)用默認(rèn)的構(gòu)造函數(shù)。動態(tài)創(chuàng)建對象舉例動態(tài)創(chuàng)建對象舉例#includeusing namespace std;class Point public: Point() X=Y=0; coutDefault Constructor called.n; Point(int xx,int yy) X=xx; Y=yy; cout Constructor called.n; Point() coutDestructor called.n; int GetX() return X; int GetY() return Y;void Move(int x,int
33、 y) X=x; Y=y; private: int X,Y;int main() coutStep One:endl; Point *Ptr1=new Point; delete Ptr1; coutStep Two:endl; Ptr1=new Point(1,2); delete Ptr1; return 0;運行結(jié)果:運行結(jié)果:Step One:Step One:Default Constructor called.Default Constructor called.Destructor called.Destructor called.Step Two:Step Two:Const
34、ructor called.Constructor called.Destructor called.Destructor called.7.1.27.1.2自由存儲區(qū)自由存儲區(qū)對象與構(gòu)造函數(shù)【例對象與構(gòu)造函數(shù)【例7.3】類說明:類說明:class CGoods string Name; int Amount; float Price; float Total_value;public: CGoods()cout調(diào)用默認(rèn)構(gòu)造函數(shù)調(diào)用默認(rèn)構(gòu)造函數(shù)endl; CGoods(string name,int amount ,float price)cout調(diào)用三參數(shù)構(gòu)造函數(shù)調(diào)用三參數(shù)構(gòu)造函數(shù)endl;
35、Name=name; Amount=amount;Price=price; Total_value=price*amount; CGoods() cout調(diào)用析構(gòu)函數(shù)調(diào)用析構(gòu)函數(shù)endl;【例【例7.37.3】演示自由存儲區(qū)對象分配和釋放?!垦菔咀杂纱鎯^(qū)對象分配和釋放。7.1.27.1.2自由存儲區(qū)自由存儲區(qū)對象與構(gòu)造函數(shù)【例對象與構(gòu)造函數(shù)【例7.3】使用:使用:int 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(); /
36、調(diào)用默認(rèn)構(gòu)造函數(shù)調(diào)用默認(rèn)構(gòu)造函數(shù) cout輸入商品類數(shù)組元素數(shù)輸入商品類數(shù)組元素數(shù)n; pc2=new CGoodsn; /動態(tài)建立數(shù)組,不能初始化,調(diào)用動態(tài)建立數(shù)組,不能初始化,調(diào)用n次默認(rèn)構(gòu)造函數(shù)次默認(rèn)構(gòu)造函數(shù) delete pc; delete pc1; delete pc2; return 0;7.1.3淺復(fù)制與深復(fù)制淺復(fù)制與深復(fù)制 淺復(fù)制:淺復(fù)制:默認(rèn)復(fù)制構(gòu)造函數(shù)默認(rèn)復(fù)制構(gòu)造函數(shù),可用一個類對象,可用一個類對象初始化另一個類對象,稱為默認(rèn)的初始化另一個類對象,稱為默認(rèn)的按成員復(fù)制,按成員復(fù)制,而不是而不是對整個類對象的對整個類對象的按位復(fù)制。按位復(fù)制。這稱為這稱為淺復(fù)制。淺復(fù)制。 圖
37、圖7.1 淺復(fù)制淺復(fù)制 P自 由 存自 由 存儲 區(qū) 對儲 區(qū) 對象象自 由 存自 由 存儲 區(qū)儲 區(qū) 對對象象PP 復(fù)制前復(fù)制前復(fù)制后復(fù)制后 如果類中有一個數(shù)據(jù)成員為指針,該類的一個對象如果類中有一個數(shù)據(jù)成員為指針,該類的一個對象obj1中中的這個指針的這個指針p,指向了動態(tài)分配的一個自由存儲區(qū)對象,(參見,指向了動態(tài)分配的一個自由存儲區(qū)對象,(參見圖圖7.1復(fù)制前),如果用復(fù)制前),如果用obj1按成員復(fù)制了一個對象按成員復(fù)制了一個對象obj2,這時,這時obj2.p也指向同一個自由存儲區(qū)對象。也指向同一個自由存儲區(qū)對象。obj1obj1obj27.1.3淺復(fù)制與深復(fù)制復(fù)制淺復(fù)制與深復(fù)制復(fù)
38、制當(dāng)當(dāng)淺復(fù)制淺復(fù)制析構(gòu)時,如用默認(rèn)的析構(gòu)析構(gòu)時,如用默認(rèn)的析構(gòu)函數(shù),則動態(tài)分配的函數(shù),則動態(tài)分配的自由存儲區(qū)自由存儲區(qū)對象不對象不能回收。如果在析構(gòu)函數(shù)中有能回收。如果在析構(gòu)函數(shù)中有“delete p;”語句,則如果先析構(gòu)函數(shù)語句,則如果先析構(gòu)函數(shù)obj1時,時,自由存儲區(qū)自由存儲區(qū)對象已經(jīng)釋放,以后再析構(gòu)對象已經(jīng)釋放,以后再析構(gòu)obj2時出現(xiàn)了二次釋放的問題。時出現(xiàn)了二次釋放的問題。自由自由存儲存儲區(qū)區(qū)對對象象PP自由自由存儲存儲區(qū)區(qū)對對象象 圖圖7.2 深復(fù)制深復(fù)制 深復(fù)制:深復(fù)制:重新定義復(fù)制的構(gòu)造函數(shù),重新定義復(fù)制的構(gòu)造函數(shù),給每個對象獨立分配一個自由存儲區(qū)給每個對象獨立分配一個自由存
39、儲區(qū)對象,稱對象,稱深復(fù)制深復(fù)制。這時先復(fù)制對象主這時先復(fù)制對象主體,再為體,再為obj2分配一個自由存儲區(qū)對分配一個自由存儲區(qū)對象,最后用象,最后用obj1的自由存儲區(qū)對象復(fù)的自由存儲區(qū)對象復(fù)制制obj2的自由存儲區(qū)對象。的自由存儲區(qū)對象。 obj1obj27.1.3淺復(fù)制與深復(fù)制淺復(fù)制與深復(fù)制【例【例7.4】定義復(fù)制構(gòu)造函數(shù)定義復(fù)制構(gòu)造函數(shù) (copy structor)和復(fù)制賦值操)和復(fù)制賦值操作符(作符(copy Assignment Operator)實現(xiàn)深復(fù)制。)實現(xiàn)深復(fù)制。 學(xué)生類定義:學(xué)生類定義:class student char *pName; /為了演示深復(fù)制,不用為了演
40、示深復(fù)制,不用string類類public: student(); /默認(rèn)構(gòu)造函數(shù)默認(rèn)構(gòu)造函數(shù) student(char *pname); /帶參數(shù)構(gòu)造函數(shù)帶參數(shù)構(gòu)造函數(shù) student(student &s); /復(fù)制構(gòu)造函數(shù)復(fù)制構(gòu)造函數(shù) student(); /析構(gòu)函數(shù)析構(gòu)函數(shù) student & operator=(student &s); ; /復(fù)制賦值操作符復(fù)制賦值操作符檢驗主函數(shù)和運行結(jié)果檢驗主函數(shù)和運行結(jié)果例例7.4 實現(xiàn)深復(fù)制實現(xiàn)深復(fù)制默認(rèn)構(gòu)造函數(shù):默認(rèn)構(gòu)造函數(shù):student:student() coutConstructor; pName=NULL;
41、 cout默認(rèn)默認(rèn)“endl;帶參數(shù)構(gòu)造函數(shù):帶參數(shù)構(gòu)造函數(shù):student:student(char *pname) coutConstructor; if(pName=new charstrlen(pname)+1) strcpy(pName,pname); coutpNameendl;例例7.4 實現(xiàn)深復(fù)制實現(xiàn)深復(fù)制復(fù)制構(gòu)造函數(shù):復(fù)制構(gòu)造函數(shù):student:student(student &s) coutCopy Constructor; if(s.pName) if(pName=new charstrlen(s.pName)+1) strcpy(pName,s.pName); else pName=NULL; coutpNameendl;析構(gòu)函數(shù):析構(gòu)函數(shù):student:student() coutDestructorpNameendl; if(pName) pName0=0; delete pName; /釋放字符串釋放字符串例例7.4 實現(xiàn)深復(fù)制實現(xiàn)深復(fù)制復(fù)制賦值操作符:復(fù)制賦值操作符:student & student:operator=(student &s) coutCopy Assign operator; delete pName;/如原來已分配,應(yīng)先撤銷,再重分配如原來已分配,
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 組織架構(gòu)及崗位職責(zé)
- 指定汽車維修服務(wù)協(xié)議
- 年度項目可行性研究報告購買合同
- 勞動合同書【鄉(xiāng)鎮(zhèn)企業(yè)】
- 園林苗木購銷合同范本
- 場地游戲安全協(xié)議書經(jīng)典版
- 2024年個人勞務(wù)協(xié)議書
- 2024股權(quán)轉(zhuǎn)讓合同協(xié)議書范本
- 辦公室裝修施工合同2024年
- 2024年南京車位租賃合同
- 期中測試卷-2024-2025學(xué)年統(tǒng)編版語文一年級上冊
- 國家基本醫(yī)療保險、工傷保險和生育保險藥品目錄(2023年)
- 人教版一年級數(shù)學(xué)上冊《第一、二單元測試卷》(附答案)
- 人教版二年級上冊數(shù)學(xué)計算題400道
- 供應(yīng)室教學(xué)課件
- 第三單元 測量(單元測試)-2024-2025學(xué)年三年級上冊數(shù)學(xué)人教版
- 1輸變電工程施工質(zhì)量驗收統(tǒng)一表式(線路工程)-2024年版
- 華為年財務(wù)報表分析(共16張課件)
- 第五單元 倍的認(rèn)識(單元測試)-2024-2025學(xué)年三年級上冊數(shù)學(xué)人教版
- 讓我們一起去追“星”!兩彈一星之核彈老人魏世杰課件高二下學(xué)期愛國主義教育主題班會
- 2024-2025學(xué)年七年級生物上冊 第二單元第一、二章 單元測試卷( 人教版)
評論
0/150
提交評論