




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第C++超詳細講解構(gòu)造函數(shù)與析構(gòu)函數(shù)的用法及實現(xiàn)目錄寫在前面構(gòu)造函數(shù)和析構(gòu)函數(shù)語法作用代碼實現(xiàn)兩大分類方式三種調(diào)用方式括號法顯示法隱式轉(zhuǎn)換法正確調(diào)用拷貝構(gòu)造函數(shù)正常調(diào)用值傳遞的方式給函數(shù)參數(shù)傳值值傳遞方式返回局部對象構(gòu)造函數(shù)的調(diào)用規(guī)則總結(jié)
寫在前面
上一節(jié)解決了類與對象封裝的問題,這一節(jié)就是對象的初始化和清理的構(gòu)造函數(shù)與析構(gòu)函數(shù)的內(nèi)容了;對象的初始化和清理也是兩個非常重要的安全問題:一個對象或者變量沒有初始狀態(tài),對其使用后果是未知,同樣的使用完一個對象或變量,沒有及時清理,也會造成一定的安全問題;c++利用了構(gòu)造函數(shù)和析構(gòu)函數(shù)解決上述問題,這兩個函數(shù)將會被編譯器自動調(diào)用,完成對象初始化和清理工作。對象的初始化和清理工作是編譯器強制要我們做的事情,因此如果我們不提供構(gòu)造和析構(gòu),編譯器提供編譯器提供的構(gòu)造函數(shù)和析構(gòu)函數(shù)是空實現(xiàn)。下面開始正文:
構(gòu)造函數(shù)和析構(gòu)函數(shù)
語法
構(gòu)造函數(shù)語法:類名(){}
1、沒有返回值也不寫void
2、函數(shù)名稱與類名相同
3、構(gòu)造函數(shù)可以有參數(shù),因此可以發(fā)生重載
4、程序在調(diào)用對象時會自動調(diào)用,無需手動調(diào)用且只會調(diào)用一次
析造函數(shù)語法:~類名(){}
1、沒有返回值也不寫void
2、函數(shù)名稱與類名相同,在名稱前加上符號~
3、構(gòu)造函數(shù)不可以有參數(shù),因此不可以發(fā)生重載
4、程序在對象銷毀前會自動調(diào)用析構(gòu),無需手動調(diào)用且只會調(diào)用一次
作用
構(gòu)造函數(shù)主要作用于創(chuàng)建對象時為對象的成員屬性賦值,構(gòu)造函數(shù)由編譯器自動調(diào)用,無須手動調(diào)用
析構(gòu)函數(shù)主要作用于對象銷毀前系統(tǒng)自動調(diào)用,執(zhí)行一些清理工作
代碼實現(xiàn)
#includeiostream
usingnamespacestd;
classPerson
public:
Person()
cout"Person構(gòu)造函數(shù)的調(diào)用"endl;
~Person()
cout"~Person析構(gòu)函數(shù)的調(diào)用"endl;
voidtest01()
Personp;//棧上的對象運行完畢后,編譯器自動釋放
intmain()
test01();
}
test01中創(chuàng)建了Person類p,主函數(shù)只是調(diào)用了一下創(chuàng)建的Person類p,編譯器就自動調(diào)用了類的構(gòu)造函數(shù)和析構(gòu)函數(shù),析構(gòu)函數(shù)是程序運行完畢后,編譯器自動清理內(nèi)存空間的時候調(diào)用的。
兩大分類方式
按參數(shù)分為有參構(gòu)造和無參構(gòu)造
按類型分為普通構(gòu)造和拷貝構(gòu)造
無參和有參構(gòu)造很好理解,就是有無參數(shù)的區(qū)別,這里講一下拷貝構(gòu)造函數(shù):
//拷貝構(gòu)造函數(shù)
Person(constPersonp)//格式:const類名引用()變量名
//講傳入的人身上的所有屬性,拷貝到我身上
age=p.age;
cout"Person的拷貝構(gòu)造函數(shù)調(diào)用"endl;
}
Person()的括號中是constPersonp,這是拷貝構(gòu)造的函數(shù)格式,他需要傳入相同類的對象,會產(chǎn)生一個具有相同屬性的類,比如p1的年齡為20,經(jīng)過拷貝構(gòu)造p2的年齡也會是20,但是兩個類對象的地址并不相同,這個到后面會具體解釋
三種調(diào)用方式
classPerson
public:
//構(gòu)造函數(shù)
Person()
cout"Person的無參構(gòu)造函數(shù)調(diào)用"endl;
Person(inta)
age=a;
cout"Person的有參構(gòu)造函數(shù)調(diào)用"endl;
//拷貝構(gòu)造函數(shù)
Person(constPersonp)//格式:const類名引用()變量名
//講傳入的人身上的所有屬性,拷貝到我身上
age=p.age;
cout"Person的拷貝構(gòu)造函數(shù)調(diào)用"endl;
~Person()
cout"~Person的析構(gòu)函數(shù)調(diào)用"endl;
intage;
};
括號法
Personp;//默認構(gòu)造函數(shù)調(diào)用
Personp2(10);//有參構(gòu)造函數(shù)
Personp3(p2);//拷貝構(gòu)造函數(shù)
cout"p2age="p2.ageendl;
cout"p3age="p3.ageendl;
注意事項:調(diào)用默認構(gòu)造函數(shù)的時候,不要加();Personp1()編譯器會認為是函數(shù)的聲明,不認為在創(chuàng)建對象,等同于voidfunc()
顯示法
Personp;
Personp2=Person(10);//有參構(gòu)造函數(shù)
Personp3=Person(p2);//拷貝構(gòu)造函數(shù)
Person(100);//匿名對象,特點:當前執(zhí)行完畢后,系統(tǒng)會立即回收掉匿名對象
cout"AAAAA"endl;
注意事項2:拷貝構(gòu)造初始化匿名對象等同于去掉括號,導致重定義,不要用拷貝構(gòu)造初始化匿名對象,如果利用匿名對象的話,會和Peronp2=Person(10),重復,出現(xiàn)重定義錯誤;也不要用拷貝構(gòu)造初始化匿名對象。
隱式轉(zhuǎn)換法
Personp2=10;//有參構(gòu)造函數(shù)
Personp3=p2;//拷貝構(gòu)造函數(shù)
這個方法不推薦使用,調(diào)用的很不明顯,建議使用前面兩個方法調(diào)用構(gòu)造函數(shù)。
正確調(diào)用拷貝構(gòu)造函數(shù)
classPerson
public:
Person()
cout"Person的無參構(gòu)造函數(shù)調(diào)用"endl;
Person(inta)
m_age=a;
cout"Person的有參構(gòu)造函數(shù)調(diào)用"endl;
Person(constPersonp)
m_age=p.m_age;
cout"Person的拷貝構(gòu)造函數(shù)調(diào)用"endl;
~Person()
cout"Person的析構(gòu)函數(shù)調(diào)用"endl;
intm_age;
};
正常調(diào)用
voidtest01()
Personp1(20);
Personp2(p1);
cout"p2的年齡為:"p2.m_ageendl;
}
主函數(shù)中直接調(diào)用test01,這時候會顯示p2的年齡為20,并且打?。嚎截悩?gòu)造函數(shù)的調(diào)用。所以說,使用一個已經(jīng)創(chuàng)建完畢的對象來初始化一個新對象的時候會調(diào)用拷貝構(gòu)造函數(shù)
值傳遞的方式給函數(shù)參數(shù)傳值
voiddoWork(Personp)
voidtest02()
Personp;
doWork(p);
}
大家可以猜一下,在主函數(shù)調(diào)用,會運行出什么結(jié)果,答案是:無參構(gòu)造函數(shù)調(diào)用和拷貝構(gòu)造函數(shù)調(diào)用,最后是兩個析構(gòu)函數(shù)調(diào)用;淺析一下過程,調(diào)用test02時創(chuàng)建了對象P,所以自動調(diào)用無參構(gòu)造函數(shù),當運行到doWork(p)時,調(diào)用拷貝構(gòu)造函數(shù),隨后拷貝構(gòu)造函數(shù)被清理,調(diào)用析構(gòu)函數(shù),程序結(jié)束前,p被清理,再次調(diào)用析構(gòu)函數(shù),程序結(jié)束。
值傳遞方式返回局部對象
PersondoWork2()
Personp1;
cout(int)p1"1"endl;
returnp1;//返回就拷貝構(gòu)造函數(shù),隨后釋放掉,調(diào)用析構(gòu)
voidtest03()
Personp=doWork2();//重新創(chuàng)建局部對象,并不是上面返回的對象p1
cout(int)p"2"endl;
}
這里doWork2返回值時Person類型,也就是說returnp1后會拷貝構(gòu)造其屬性給test03調(diào)用的p,但是p1和p2并不是同一個對象,我們可以輸出他們的地址來驗證。
這里的調(diào)用順序是:PersonP1的無參構(gòu)造,隨后輸出p1地址,然后返回值的時候先調(diào)用拷貝構(gòu)造函數(shù),把值賦給p,隨后清理p1調(diào)用析構(gòu);然后回到test03中,輸出p的地址,程序結(jié)束前調(diào)用析構(gòu),程序結(jié)束。
構(gòu)造函數(shù)的調(diào)用規(guī)則
編譯器提供:
1、創(chuàng)建一個類,c++編譯器會給每個類都至少添加三個函數(shù)
默認構(gòu)造(空實現(xiàn))析構(gòu)函數(shù)(空實現(xiàn))值拷貝構(gòu)造(值拷貝)
2、如果我們寫了有參構(gòu)造,編譯器不再提供默認構(gòu)造,但是提供值拷貝構(gòu)造
如果我們寫了拷貝構(gòu)造函數(shù),編譯器不再提供其他普通構(gòu)造函數(shù)
voidtest01()
Personp1;
p1.m_age=19;
Personp2(p1);//即使沒寫拷貝構(gòu)造仍然能得到結(jié)果p2.m_age=19
cout"p2的年齡為:"p2.m_ageendl;
}
也就是說,就算我們不寫無參和拷貝構(gòu)造,調(diào)用test03也會得到值拷貝后的p2年齡,這是編譯器默認提供的三個函數(shù)。但是如果寫
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 法治思想面試題及答案
- 護士交班考試題及答案
- 鄉(xiāng)鎮(zhèn)副職面試題及答案
- 預防感冒面試題及答案
- 恐懼死亡測試題及答案
- 家電公司法律事務管理辦法
- 家電公司聲譽風險管理規(guī)定
- 2.4圓周角(第1課時圓周角定理)(教學課件)數(shù)學蘇科版九年級上冊
- 保安執(zhí)勤裝備使用課件
- 保安崗位知識培訓課件
- 老年上消化道出血急診診療專家共識(2024版)解讀
- 化工過程安全管理導則AQT 3034-2022知識培訓
- 水庫閘門維修合同范例
- 2024屆新高考語文高中古詩文必背72篇 【原文+注音+翻譯】
- 車輛運輸協(xié)議書
- 家庭成員及主要社會關(guān)系的政審材料
- 光伏設(shè)計施工圖總說明
- 網(wǎng)絡(luò)設(shè)備項目驗收方案
- 2024年首屆全國“紅旗杯”班組長大賽考試題庫1400題(含答案)
- 《婚姻家庭輔導服務規(guī)范》
- 高鐵保潔報告
評論
0/150
提交評論