C++實現(xiàn)拷貝構(gòu)造函數(shù)的方法詳解_第1頁
C++實現(xiàn)拷貝構(gòu)造函數(shù)的方法詳解_第2頁
C++實現(xiàn)拷貝構(gòu)造函數(shù)的方法詳解_第3頁
C++實現(xiàn)拷貝構(gòu)造函數(shù)的方法詳解_第4頁
C++實現(xiàn)拷貝構(gòu)造函數(shù)的方法詳解_第5頁
已閱讀5頁,還剩3頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第C++實現(xiàn)拷貝構(gòu)造函數(shù)的方法詳解目錄引入一.什么是拷貝構(gòu)造函數(shù)二.什么情況下使用拷貝構(gòu)造函數(shù)三.使用拷貝構(gòu)造函數(shù)需要注意什么四.深拷貝淺拷貝4.1淺拷貝4.2深拷貝

引入

對于普通類型的對象來說,他們之間的復(fù)制很簡單:

inta=10;

intb=a;

但是對于類對象來說,其中會存在許多的成員變量。

#includeiostream

usingnamespacestd;

classCExample{

private:

inta;

public:

//構(gòu)造函數(shù)

CExample(intb)

{a=b;}

//一般函數(shù)

voidShow()

coutaendl;

intmain()

CExampleA(100);

CExampleB=A;//注意這里的對象初始化要調(diào)用拷貝構(gòu)造函數(shù),而非賦值

B.Show();

return0;

從以上代碼可以看出系統(tǒng)為對象B分配了內(nèi)存并完成了與對象A的復(fù)制過程。就類對象而言,相同類型的類對象是通過拷貝構(gòu)造函數(shù)來完成整個復(fù)制過程的。

下面這個則是拷貝構(gòu)造函數(shù)的工作過程

#includeiostream

usingnamespacestd;

classCExample{

private:

inta;

public:

//構(gòu)造函數(shù)

CExample(intb)

{a=b;}

//拷貝構(gòu)造函數(shù)

CExample(constCExampleC)

a=C.a;

//一般函數(shù)

voidShow()

coutaendl;

intmain()

CExampleA(100);

CExampleB=A;//CExampleB(A);也是一樣的

B.Show();

return0;

在這里CExample(constCExampleC)就是我們自定義的拷貝構(gòu)造函數(shù)。

一.什么是拷貝構(gòu)造函數(shù)

同一個類的對象在內(nèi)存中有完全相同的結(jié)構(gòu),如果作為一個整體進行復(fù)制或稱拷貝是完全可行的。這個拷貝過程只需要拷貝數(shù)據(jù)成員,而函數(shù)成員是共用的(只有一份拷貝)。在建立對象時可用同一類的另一個對象來初始化該對象的存儲空間,這時所用的構(gòu)造函數(shù)稱為拷貝構(gòu)造函數(shù)。

拷貝構(gòu)造函數(shù)本質(zhì)上來說也是構(gòu)造函數(shù)。

二.什么情況下使用拷貝構(gòu)造函數(shù)

一般來說有以下三種情況:

用舊對象去初始化新對象值傳遞參數(shù)是類類型的值類型,從實參傳遞給形參的過程,是用實參去構(gòu)造形參函數(shù)返回值是值類型用局部對象去構(gòu)造臨時對象調(diào)用拷貝構(gòu)造

classA

public:

A(inti=0):m_i(i)

cout"A(int)"m_iendl;

A(constAa):m_i(a.m_i)

cout"A(A)"m_iendl;

~A()

cout"~A"m_iendl;

private:

intm_i;

voidfn(At)//2.將c傳遞給t的過程,是值傳遞,此時臨時對象形參t是新對象,用c去構(gòu)造t,調(diào)用拷貝構(gòu)造

cout"fnend"endl;

//在退出fn函數(shù)時,將臨時對象t釋放,調(diào)用析構(gòu)函數(shù)

Atest()

Ad(40);//調(diào)用普通構(gòu)造A(int)構(gòu)造對象d

returnd;

3.在返回的時候,將局部對象的值給了臨時對象(值傳遞,調(diào)用拷貝構(gòu)造,用舊局部對象去構(gòu)造新的臨時對象)

然后局部對象d就釋放了,臨時對象將值帶回到主調(diào)函數(shù)中后,臨時對象的值才釋放

Afnn()

As(50);//A(int)50

returns;//

/*1.s-臨時對象拷貝構(gòu)造

2.析構(gòu)函數(shù)局部對象s

voidmain()

Aa(20);//A(int)20

Ab=a;//1.用a初始化bA(A)

cout"fn"endl;

Ac(30);//A(int)30

fn(c);

cout"test"endl;

c=test();//臨時對象將值賦給c(調(diào)用賦值函數(shù))之后,調(diào)用析構(gòu),析構(gòu)臨時對象

cout"fnn"endl;

At=fnn();//臨時對象初始化新對象t,是否會調(diào)用拷貝構(gòu)造--調(diào)用了,不過編譯器做過優(yōu)化

cout"mainend"endl;

三.使用拷貝構(gòu)造函數(shù)需要注意什么

拷貝構(gòu)造函數(shù)是構(gòu)造函數(shù)的一個重載形式。

拷貝構(gòu)造函數(shù)的參數(shù)只有一個且必須使用引用傳參,使用傳值方式會引發(fā)無窮遞歸調(diào)用。

若未顯示定義,系統(tǒng)生成默認的拷貝構(gòu)造函數(shù)。默認的拷貝構(gòu)造函數(shù)對象按內(nèi)存存儲按字節(jié)序完成拷貝,稱為:位拷貝。

四.深拷貝淺拷貝

4.1淺拷貝

所謂淺拷貝,指的是在對象復(fù)制時,只對對象中的數(shù)據(jù)成員進行簡單的賦值,默認拷貝構(gòu)造函數(shù)執(zhí)行的也是淺拷貝。大多情況下淺拷貝已經(jīng)能很好地工作了,但是一旦對象存在了動態(tài)成員,指針,那么淺拷貝就會出現(xiàn)一些問題。

對于下面函數(shù)來說有指針作為數(shù)據(jù)成員,則用s1對象去構(gòu)造s2對象的時候,調(diào)用默認拷貝構(gòu)造,用s1中的數(shù)據(jù)成員指針m_str去初始化s2對象中的數(shù)據(jù)成員m_str,即是s2.m_str=s1.m_str,那么導(dǎo)致兩個對象中的指針指向同一塊內(nèi)存單元,指向的都是構(gòu)造s1對象時開辟的內(nèi)存單元,所以在主函數(shù)退出時候要析構(gòu)s2和s1時,將同一段空間釋放兩次出現(xiàn)內(nèi)存錯誤。

classStr

public:

Str(constchar*str="")

m_str=newchar[strlen(str)+1];

strcpy(m_str,str);

~Str()

delete[]m_str;

voidPrint()

coutm_strendl;

private:

char*m_str;

voidmain()

Strs1("pangpang");

Strs2(s1);

coutsizeof(Str)endl;

s1.Print();

s2.Print();

}

上述程序的內(nèi)存布局:

對于指針作為數(shù)據(jù)成員的類,用s1對象去構(gòu)造s2對象的時候,調(diào)用默認拷貝構(gòu)造函數(shù)時,二者指向同一內(nèi)存單元,即二者的初始地址相同這里均為0X0002000,當我們構(gòu)造完以后將要進行析構(gòu)時,這里將會出現(xiàn)錯誤:因為析構(gòu)函數(shù)要釋放空間,而這里我們的空間對應(yīng)的是一塊空間,當我們析構(gòu)完s2后:這一塊空間的內(nèi)容已經(jīng)被delete,而我們還需要析構(gòu)s1,即:一個內(nèi)存空間析構(gòu)了兩次,出現(xiàn)內(nèi)存錯誤。

為了解決上述問題我們就需要給s2中的m_str也開辟和s1中的m_str一樣大小的空間,所以我們就需要深拷貝。

4.2深拷貝

在深拷貝的情況下,對于對象中動態(tài)成員,就不能僅僅簡單地賦值了,而應(yīng)該重新動態(tài)分配空間,如上面的例子就應(yīng)該按照如下的方式進行處理:

classStr

public:

Str(constchar*str="")

m_str=newchar[strlen(str)+1];

strcpy(m_str,str);

~Str()

cout"~Str"endl;

delete[]m_str;

Str(constStrs)

cout"Str(Str)"endl;

m_str=newchar[strlen(s.m_str)+1];//開辟同樣大小的空間

strcpy(m_str,s.m_str);//將內(nèi)容拷貝成一樣的

voidPrint()

coutm_stren

溫馨提示

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

評論

0/150

提交評論