13圖解析C++構(gòu)造函數(shù)和析構(gòu)函數(shù),C++零基礎(chǔ)教程

前言
上一章節(jié)主要是詳細(xì)介紹了C++中的類和對(duì)象。不清楚的可以回顧一下哦。本章節(jié)主要針對(duì)于C++構(gòu)造函數(shù)和析構(gòu)做以詳細(xì)介紹。

構(gòu)造函數(shù)
構(gòu)造函數(shù)是C++類中的一個(gè)特殊的函數(shù),主要有以下特點(diǎn):
構(gòu)造函數(shù)的名字必須與類名相同。
構(gòu)造函數(shù)沒有返回值。
構(gòu)造函數(shù)也是特殊的成員函數(shù),
構(gòu)造函數(shù)可以重載
構(gòu)造函數(shù)一般被聲明為公有函數(shù)
默認(rèn)構(gòu)造函數(shù):不寫構(gòu)造函數(shù),存在無參的構(gòu)造函數(shù)
自動(dòng)調(diào)用:構(gòu)造對(duì)象時(shí)被調(diào)用
調(diào)用順序:創(chuàng)建對(duì)象時(shí)調(diào)用構(gòu)造函數(shù)
故我們可以寫出如下代碼:

寫一個(gè)構(gòu)造函數(shù)就是這么簡單的哦!
談?wù)勀J(rèn)構(gòu)造函數(shù)
當(dāng)我們不寫構(gòu)造函數(shù)的時(shí)候,為什么可以創(chuàng)建對(duì)象,是因?yàn)椴粚憳?gòu)造函數(shù),存在一個(gè)無參的構(gòu)造函數(shù),所以我們可以構(gòu)造無參對(duì)象。其實(shí)這個(gè)默認(rèn)的函數(shù)我們可以刪除掉的,通過C++delete 提供的函數(shù)去刪除默認(rèn)的函數(shù),這樣的就無法創(chuàng)建對(duì)象了。或者你把構(gòu)造函數(shù)私有化也是可以的。

從這一點(diǎn)上來看,可以驗(yàn)證默認(rèn)的構(gòu)造函數(shù)其實(shí)也是無參的。
談?wù)剺?gòu)造函數(shù)與對(duì)象的創(chuàng)建
構(gòu)造函數(shù)通常是用來創(chuàng)建對(duì)象,也可以理解為對(duì)象的屬性初始化也可以。并且構(gòu)造函數(shù)決定了對(duì)象的長相,構(gòu)造函數(shù)是無參的調(diào)用無參構(gòu)造函數(shù),對(duì)象一個(gè)參數(shù),構(gòu)造的對(duì)象也就只有一個(gè)參數(shù)。依次類推要保持一致性。

所以一般情況我們?yōu)榱藰?gòu)建不同的對(duì)象,習(xí)慣于把構(gòu)造函數(shù)寫成缺省的形態(tài),這樣就方便了我們構(gòu)建不同的對(duì)象。
談?wù)刵ew一個(gè)對(duì)象的過程
new一個(gè)對(duì)象其實(shí)是兩個(gè)過程:
new一個(gè)無名對(duì)象
把無名對(duì)象的首地址給對(duì)象指針
所以new一個(gè)對(duì)象的時(shí)候也需要和構(gòu)造函數(shù)的參數(shù)一致,如以下代碼:

談?wù)効截悩?gòu)造函數(shù)
默認(rèn)拷貝構(gòu)造函數(shù)
拷貝構(gòu)造函數(shù)也是構(gòu)造函數(shù),所以也可以用來構(gòu)造對(duì)象的,一般不寫拷貝構(gòu)造函數(shù)也是可以使用默認(rèn)的拷貝構(gòu)造函數(shù)去實(shí)現(xiàn)對(duì)象的創(chuàng)建,拷貝構(gòu)造函數(shù)只有唯一的一個(gè)參數(shù)就是對(duì)對(duì)象的引用,通過拷貝構(gòu)造函數(shù)創(chuàng)建對(duì)象的時(shí)候需要傳入一個(gè)參數(shù),如下代碼:

自己也是可以寫一個(gè)拷貝構(gòu)造函數(shù),如下代碼:

這里this代表的是所有類對(duì)象的抽象地址,描述每一個(gè)類的想的行為,*this表示對(duì)象本身,實(shí)現(xiàn)object拷貝到*this。值得一提的是在定義過程當(dāng)中的賦值運(yùn)算也是調(diào)用拷貝構(gòu)造函數(shù):

注意普通的賦值運(yùn)算并不會(huì)調(diào)用拷貝構(gòu)造函數(shù)如下代碼:
析構(gòu)函數(shù)
析構(gòu)函數(shù)也是C++類中的一個(gè)特殊的函數(shù),主要有以下特點(diǎn):
析構(gòu)函數(shù)的名字必須~類名。
析構(gòu)函數(shù)沒有返回值。
析構(gòu)函數(shù)沒有參數(shù),所以不可重載。
自動(dòng)調(diào)用:析構(gòu)函數(shù)在對(duì)象死亡調(diào)用
調(diào)用順序:一般情況和創(chuàng)建順序相反
什么時(shí)候需要寫析構(gòu)函數(shù)呢?一般當(dāng)類中的數(shù)據(jù)成員進(jìn)行了內(nèi)存的申請(qǐng)過程,一般都是需要自己手動(dòng)寫析構(gòu)函數(shù)的,如一下代碼:

上述代碼主要有三部分組成
構(gòu)造函數(shù)中:給予屬性name申請(qǐng)內(nèi)存
主函數(shù)中:{}可以提早限制對(duì)象的作用域
析構(gòu)函數(shù)中:釋放申請(qǐng)的內(nèi)存
深拷貝和淺拷貝
為什么有深拷貝和淺拷貝?主要是在使用拷貝構(gòu)造函數(shù)的時(shí)候,對(duì)一段內(nèi)存重復(fù)釋放,導(dǎo)致析構(gòu)問題,如一下代碼:

因?yàn)檫@兩個(gè)個(gè)對(duì)象的name屬性都是指向同一個(gè)內(nèi)存,所以重復(fù)釋放內(nèi)存導(dǎo)致了析構(gòu)問題。所以才要使用深拷貝去解決這個(gè)問題,深拷貝其實(shí)很簡單,就是在拷貝構(gòu)造函數(shù)中另外申請(qǐng)一段內(nèi)存,讓對(duì)象擁有自己的專屬內(nèi)存,實(shí)際代碼如下:

各自有各自的內(nèi)存,互不干擾,完美解決問題。
構(gòu)造順序和析構(gòu)順序
一般情況是構(gòu)造順序和析構(gòu)順序正好是相反的,如一下代碼

其實(shí)很簡單,如果你明白變量的作用域其實(shí)就很容易理解調(diào)用順序的。普通對(duì)象構(gòu)造順序和析構(gòu)順序正好是相反的,new出來的對(duì)象,釋放完后就會(huì)調(diào)用析構(gòu)函數(shù),靜態(tài)對(duì)象,程序關(guān)閉后調(diào)用,所以上圖沒有顯示出來4的析構(gòu)過程。
對(duì)象數(shù)組問題
對(duì)象數(shù)組其實(shí)本身就是多個(gè)普通的對(duì)象,所以當(dāng)不存在無參的構(gòu)造函數(shù)時(shí)候不能構(gòu)建無參的數(shù)組對(duì)象,如一下代碼:

所以我們要像在C語言中那樣創(chuàng)建數(shù)組的話, 都會(huì)準(zhǔn)備一個(gè)無參的構(gòu)造函數(shù),或者是采用缺省的方式編寫構(gòu)造函數(shù)。
尾言
關(guān)于類的組合問題,我們下個(gè)章節(jié)探討,本節(jié)課就到這里了,本章節(jié)作業(yè): 用C++類的方式實(shí)現(xiàn)C語言中的單鏈表。
上一章節(jié):C++類和對(duì)象,可以關(guān)注微信公眾號(hào),即可閱讀更多教程哦!
