C++類對象的深拷貝淺拷貝構(gòu)造函數(shù)_第1頁
C++類對象的深拷貝淺拷貝構(gòu)造函數(shù)_第2頁
C++類對象的深拷貝淺拷貝構(gòu)造函數(shù)_第3頁
C++類對象的深拷貝淺拷貝構(gòu)造函數(shù)_第4頁
C++類對象的深拷貝淺拷貝構(gòu)造函數(shù)_第5頁
已閱讀5頁,還剩3頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、C+類對象的深拷貝、淺拷貝構(gòu)造函數(shù)學(xué)習(xí)過類的構(gòu)造函數(shù)和析構(gòu)函數(shù)的相關(guān)知識,對于普通類型的對象來說,他們之間的復(fù)制是很簡單的,例如:int a = 10; int b =a;自己定義的類的對象同樣是對象,誰也不能阻止我們用以下的方式進行復(fù)制,例如:#include Using namespace std; Class Test public: Test(int temp) p1=temp; protected: Int p1; ; Void main() Test a(99); Test b=a; 普通對象和類對象同為對象,他們之間的特性有相似之處也有不同之處,類對象內(nèi)部存在成員變量,而普通對象

2、是沒有的,當同樣的復(fù)制方法發(fā)生在不同的對象上的時候,那么系統(tǒng)對他們進行的操作也是不一樣的,就類對象而言,相同類型的類對象是通過拷貝構(gòu)造函數(shù)來完成整個復(fù)制過程的,在上面的代碼中,我們并沒有看到拷貝構(gòu)造函數(shù),同樣完成了復(fù)制工作,這又是為什么呢?因為當一個類沒有自定義的拷貝構(gòu)造函數(shù)的時候系統(tǒng)會自動提供一個默認的拷貝構(gòu)造函數(shù),來完成復(fù)制工作。下面,我們?yōu)榱苏f明情況,就普通情況而言(以上面的代碼為例),我們來自己定義一個與系統(tǒng)默認拷貝構(gòu)造函數(shù)一樣的拷貝構(gòu)造函數(shù),看看它的內(nèi)部是如何工作的!代碼如下:#include usingnamespacestd; classTest public: Test(int

3、temp) p1=temp; Test(Test &c_t)/這里就是自定義的拷貝構(gòu)造函數(shù) cout進入copy構(gòu)造函數(shù)p1=c_t.p1;/這句如果去掉就不能完成復(fù)制工作了,此句復(fù)制過程的核心語句 public: intp1; ; voidmain() Test a(99); Test b=a; coutcin.get(); 上面代碼中的Test(Test &c_t)就是我們自定義的拷貝構(gòu)造函數(shù),拷貝構(gòu)造函數(shù)的名稱必須與類名稱一致,函數(shù)的形式參數(shù)是本類型的一個引用變量,且必須是引用。當用一個已經(jīng)初始化過了的自定義類類型對象去初始化另一個新構(gòu)造的對象的時候,拷貝構(gòu)造函數(shù)就會被自動調(diào)用,如果你沒

4、有自定義拷貝構(gòu)造函數(shù)的時候系統(tǒng)將會提供給一個默認的拷貝構(gòu)造函數(shù)來完成這個過程,上面代碼的復(fù)制核心語句就是通過Test(Test &c_t)拷貝構(gòu)造函數(shù)內(nèi)的p1=c_t.p1;語句完成的。如果取掉這句代碼,那么b對象的p1屬性將得到一個未知的隨機值;下面我們來討論一下關(guān)于淺拷貝和深拷貝的問題。就上面的代碼情況而言,很多人會問到,既然系統(tǒng)會自動提供一個默認的拷貝構(gòu)造函數(shù)來處理復(fù)制,那么我們沒有意義要去自定義拷貝構(gòu)造函數(shù)呀,對,就普通情況而言這的確是沒有必要的,但在某寫狀況下,類體內(nèi)的成員是需要開辟動態(tài)開辟堆內(nèi)存的,如果我們不自定義拷貝構(gòu)造函數(shù)而讓系統(tǒng)自己處理,那么就會導(dǎo)致堆內(nèi)存的所屬權(quán)產(chǎn)生混亂,試

5、想一下,已經(jīng)開辟的一端堆地址原來是屬于對象a的,由于復(fù)制過程發(fā)生,b對象取得是a已經(jīng)開辟的堆地址,一旦程序產(chǎn)生析構(gòu),釋放堆的時候,計算機是不可能清楚這段地址是真正屬于誰的,當連續(xù)發(fā)生兩次析構(gòu)的時候就出現(xiàn)了運行錯誤。為了更詳細的說明問題,請看如下的代碼。#include usingnamespacestd; classInternet public: Internet(char*name,char*address) cout載入構(gòu)造函數(shù)strcpy(Internet:name,name); strcpy(Internet:address,address); cname=newcharstrlen

6、(name)+1; if(cname!=NULL) strcpy(Internet:cname,name); Internet(Internet &temp) cout載入COPY構(gòu)造函數(shù)strcpy(Internet:name,); strcpy(Internet:address,temp.address); cname=newcharstrlen(name)+1;/這里注意,深拷貝的體現(xiàn)! if(cname!=NULL) strcpy(Internet:cname,name); Internet() cout載入析構(gòu)函數(shù)!; delete cname; cin.get()

7、; voidshow(); protected: charname20; charaddress30; char*cname; ; voidInternet:show() cout voidtest(Internet ts) cout載入test函數(shù) voidmain() Internet a(中國軟件開發(fā)實驗室,dev-); Internet b =a; b.show(); test(b); 上面代碼就演示了深拷貝的問題,對對象b的cname屬性采取了新開辟內(nèi)存的方式避免了內(nèi)存歸屬不清所導(dǎo)致析構(gòu)釋放空間時候的錯誤,最后我必須提一下,對于上面的程序我的解釋并不多,就是希望讀者本身運行程序觀察變

8、化,進而深刻理解。深拷貝和淺拷貝的定義可以簡單理解成:如果一個類擁有資源(堆,或者是其它系統(tǒng)資源),當這個類的對象發(fā)生復(fù)制過程的時候,這個過程就可以叫做深拷貝,反之對象存在資源但復(fù)制過程并未復(fù)制資源的情況視為淺拷貝。淺拷貝資源后在釋放資源的時候會產(chǎn)生資源歸屬不清的情況導(dǎo)致程序運行出錯,這點尤其需要注意!以前我們的教程中討論過函數(shù)返回對象產(chǎn)生臨時變量的問題,接下來我們來看一下在函數(shù)中返回自定義類型對象是否也遵循此規(guī)則產(chǎn)生臨時對象!先運行下列代碼:#include usingnamespacestd; classInternet public: Internet() ; Internet(char

9、*name,char*address) cout載入構(gòu)造函數(shù)strcpy(Internet:name,name); strcpy(Internet:address,address); Internet(Internet &temp) cout載入COPY構(gòu)造函數(shù)strcpy(Internet:name,); strcpy(Internet:address,temp.address); cin.get(); Internet() cout載入析構(gòu)函數(shù)!; cin.get(); protected: charname20; charaddress20; ; Internet tp

10、() Internet b(中國軟件開發(fā)實驗室,dev-); returnb; voidmain() Internet a; a=tp(); 從上面的代碼運行結(jié)果可以看出,程序一共載入過析構(gòu)函數(shù)三次,證明了由函數(shù)返回自定義類型對象同樣會產(chǎn)生臨時變量,事實上對象a得到的就是這個臨時Internet類類型對象temp的值。這一下節(jié)的內(nèi)容我們來說一下無名對象。利用無名對象初始化對象系統(tǒng)不會不調(diào)用拷貝構(gòu)造函數(shù)。那么什么又是無名對象呢?很簡單,如果在上面程序的main函數(shù)中有:Internet(中國軟件開發(fā)實驗室,dev-);這樣的一句語句就會產(chǎn)生一個無名對象,無名對象會調(diào)用構(gòu)造函數(shù)但利用無名對象初始化

11、對象系統(tǒng)不會不調(diào)用拷貝構(gòu)造函數(shù)!下面三段代碼是很見到的三種利用無名對象初始化對象的例子。#include usingnamespacestd; classInternet public: Internet(char*name,char*address) cout載入構(gòu)造函數(shù)strcpy(Internet:name,name); Internet(Internet &temp) cout載入COPY構(gòu)造函數(shù)strcpy(Internet:name,); cin.get(); Internet() cout載入析構(gòu)函數(shù)!; cin.get(); public: charname2

12、0; charaddress20; ; voidmain() Internet a=Internet(中國軟件開發(fā)實驗室,dev-); coutcin.get(); 上面代碼的運行結(jié)果有點“出人意料”,從思維邏輯上說,當無名對象創(chuàng)建了后,是應(yīng)該調(diào)用自定義拷貝構(gòu)造函數(shù),或者是默認拷貝構(gòu)造函數(shù)來完成復(fù)制過程的,但事實上系統(tǒng)并沒有這么做,因為無名對象使用過后在整個程序中就失去了作用,對于這種情況c+會把代碼看成是:Internet a(中國軟件開發(fā)實驗室,dev-);省略了創(chuàng)建無名對象這一過程,所以說不會調(diào)用拷貝構(gòu)造函數(shù)。最后讓我們來看看引用無名對象的情況。#include usingnamespacestd; classInternet public: Internet(char*name,char*address) cout載入構(gòu)造函數(shù)strcpy(Internet:name,name); Internet(Internet &temp) cout載入COPY構(gòu)造函數(shù)strcpy(Internet:name,); cin.get(); Internet() cout載入析構(gòu)函數(shù)!; public: charname20; charaddress20; ; voidmain() Internet &a=Intern

溫馨提示

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

評論

0/150

提交評論