




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第C++實(shí)現(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ù)來完成整個(gè)復(fù)制過程的。
下面這個(gè)則是拷貝構(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ù)
同一個(gè)類的對象在內(nèi)存中有完全相同的結(jié)構(gòu),如果作為一個(gè)整體進(jìn)行復(fù)制或稱拷貝是完全可行的。這個(gè)拷貝過程只需要拷貝數(shù)據(jù)成員,而函數(shù)成員是共用的(只有一份拷貝)。在建立對象時(shí)可用同一類的另一個(gè)對象來初始化該對象的存儲空間,這時(shí)所用的構(gòu)造函數(shù)稱為拷貝構(gòu)造函數(shù)。
拷貝構(gòu)造函數(shù)本質(zhì)上來說也是構(gòu)造函數(shù)。
二.什么情況下使用拷貝構(gòu)造函數(shù)
一般來說有以下三種情況:
用舊對象去初始化新對象值傳遞參數(shù)是類類型的值類型,從實(shí)參傳遞給形參的過程,是用實(shí)參去構(gòu)造形參函數(shù)返回值是值類型用局部對象去構(gòu)造臨時(shí)對象調(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的過程,是值傳遞,此時(shí)臨時(shí)對象形參t是新對象,用c去構(gòu)造t,調(diào)用拷貝構(gòu)造
cout"fnend"endl;
//在退出fn函數(shù)時(shí),將臨時(shí)對象t釋放,調(diào)用析構(gòu)函數(shù)
Atest()
Ad(40);//調(diào)用普通構(gòu)造A(int)構(gòu)造對象d
returnd;
3.在返回的時(shí)候,將局部對象的值給了臨時(shí)對象(值傳遞,調(diào)用拷貝構(gòu)造,用舊局部對象去構(gòu)造新的臨時(shí)對象)
然后局部對象d就釋放了,臨時(shí)對象將值帶回到主調(diào)函數(shù)中后,臨時(shí)對象的值才釋放
Afnn()
As(50);//A(int)50
returns;//
/*1.s-臨時(shí)對象拷貝構(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();//臨時(shí)對象將值賦給c(調(diào)用賦值函數(shù))之后,調(diào)用析構(gòu),析構(gòu)臨時(shí)對象
cout"fnn"endl;
At=fnn();//臨時(shí)對象初始化新對象t,是否會調(diào)用拷貝構(gòu)造--調(diào)用了,不過編譯器做過優(yōu)化
cout"mainend"endl;
三.使用拷貝構(gòu)造函數(shù)需要注意什么
拷貝構(gòu)造函數(shù)是構(gòu)造函數(shù)的一個(gè)重載形式。
拷貝構(gòu)造函數(shù)的參數(shù)只有一個(gè)且必須使用引用傳參,使用傳值方式會引發(fā)無窮遞歸調(diào)用。
若未顯示定義,系統(tǒng)生成默認(rèn)的拷貝構(gòu)造函數(shù)。默認(rèn)的拷貝構(gòu)造函數(shù)對象按內(nèi)存存儲按字節(jié)序完成拷貝,稱為:位拷貝。
四.深拷貝淺拷貝
4.1淺拷貝
所謂淺拷貝,指的是在對象復(fù)制時(shí),只對對象中的數(shù)據(jù)成員進(jìn)行簡單的賦值,默認(rèn)拷貝構(gòu)造函數(shù)執(zhí)行的也是淺拷貝。大多情況下淺拷貝已經(jīng)能很好地工作了,但是一旦對象存在了動(dòng)態(tài)成員,指針,那么淺拷貝就會出現(xiàn)一些問題。
對于下面函數(shù)來說有指針作為數(shù)據(jù)成員,則用s1對象去構(gòu)造s2對象的時(shí)候,調(diào)用默認(rèn)拷貝構(gòu)造,用s1中的數(shù)據(jù)成員指針m_str去初始化s2對象中的數(shù)據(jù)成員m_str,即是s2.m_str=s1.m_str,那么導(dǎo)致兩個(gè)對象中的指針指向同一塊內(nèi)存單元,指向的都是構(gòu)造s1對象時(shí)開辟的內(nèi)存單元,所以在主函數(shù)退出時(shí)候要析構(gòu)s2和s1時(shí),將同一段空間釋放兩次出現(xiàn)內(nèi)存錯(cuò)誤。
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對象的時(shí)候,調(diào)用默認(rèn)拷貝構(gòu)造函數(shù)時(shí),二者指向同一內(nèi)存單元,即二者的初始地址相同這里均為0X0002000,當(dāng)我們構(gòu)造完以后將要進(jìn)行析構(gòu)時(shí),這里將會出現(xiàn)錯(cuò)誤:因?yàn)槲鰳?gòu)函數(shù)要釋放空間,而這里我們的空間對應(yīng)的是一塊空間,當(dāng)我們析構(gòu)完s2后:這一塊空間的內(nèi)容已經(jīng)被delete,而我們還需要析構(gòu)s1,即:一個(gè)內(nèi)存空間析構(gòu)了兩次,出現(xiàn)內(nèi)存錯(cuò)誤。
為了解決上述問題我們就需要給s2中的m_str也開辟和s1中的m_str一樣大小的空間,所以我們就需要深拷貝。
4.2深拷貝
在深拷貝的情況下,對于對象中動(dòng)態(tài)成員,就不能僅僅簡單地賦值了,而應(yīng)該重新動(dòng)態(tài)分配空間,如上面的例子就應(yīng)該按照如下的方式進(jìn)行處理:
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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 46270-2025農(nóng)業(yè)機(jī)械北斗自動(dòng)駕駛系統(tǒng)
- 2025貴州醫(yī)科大學(xué)第三附屬醫(yī)院第十三屆貴州人才博覽會引才5人模擬試卷附答案詳解(黃金題型)
- 2025黑龍江黑河市愛輝區(qū)花園社區(qū)衛(wèi)生服務(wù)中心招聘非事業(yè)編制人員7人考前自測高頻考點(diǎn)模擬試題帶答案詳解
- 2025湖南省兒童醫(yī)院高層次人才公開招聘16人模擬試卷及答案詳解(奪冠)
- 2025北京市昌平區(qū)人民法院招聘輔助書記員2人考前自測高頻考點(diǎn)模擬試題附答案詳解(考試直接用)
- 2025北京市海淀區(qū)中關(guān)村第二小學(xué)科學(xué)城北區(qū)分校招聘考前自測高頻考點(diǎn)模擬試題及答案詳解(有一套)
- 2025年甘肅省蘭州眼科醫(yī)院(蘭州市第一人民醫(yī)院眼科)招聘模擬試卷帶答案詳解
- 2025年中國環(huán)保絕緣管行業(yè)市場分析及投資價(jià)值評估前景預(yù)測報(bào)告
- 2025年甘肅酒泉玉門市招聘村級后備干部模擬試卷(含答案詳解)
- 2025第十三屆貴州人才博覽會貴州水利水電職業(yè)技術(shù)學(xué)院引進(jìn)人才12人模擬試卷(含答案詳解)
- 二年級趣味數(shù)學(xué)校本教材
- JJF新1422024電動(dòng)汽車充電檢測用程控電阻負(fù)載校準(zhǔn)規(guī)范
- 當(dāng)代主要疾病和預(yù)防課件2025-2026學(xué)年北師大版生物八年級上冊
- 葡萄種植培訓(xùn)課件
- 車輛入股協(xié)議書范本合同
- 好利來工作協(xié)議合同模板
- 人防檢測培訓(xùn)課件
- 2025年睡眠監(jiān)護(hù)儀項(xiàng)目申請報(bào)告范文
- 征地拆遷業(yè)務(wù)知識培訓(xùn)課件
- 3.1 世界是普遍聯(lián)系的 課件 高中政治統(tǒng)編版必修4 哲學(xué)與文化
- 中國河流黃河課件
評論
0/150
提交評論