5 繼承中的構造與析構

2021-10-08 19:29:05 字數 2867 閱讀 5284

這一節主要解決這樣的乙個問題:如何初始化父類成員?父類建構函式和子類建構函式有什麼關係?

必須對繼承而來的成員進行初始化:

-----直接呼叫初始化列表或者賦值的方式進行(麻煩一點,所以不建議使用)

-----呼叫父類建構函式進行初始化,呼叫方式如下:

(1)預設呼叫

適用於無參建構函式或者是使用預設引數的建構函式

(2)顯式呼叫

通過初始化列表進行呼叫

適用於所有父類建構函式

例程:

#include

#include

using

namespace std;

class

parent

parent

(string s)};

class

child

:public parent

child

(string s)

:parent

(s)}

;int

main()

執行結果:

分析:當子類呼叫父類的建構函式的時候,如果此時父類沒有無參建構函式或者預設建構函式,程式是報錯的,因此這個時候要麼在父類中提供無參建構函式或者預設建構函式,要麼在子類中通過初始化列表對父類建構函式進行呼叫,這樣子才能夠通過程式

總結:子類物件在建立之時會首先呼叫父類的建構函式

先執行父類的建構函式再執行子類的建構函式

父類的建構函式可以被隱式呼叫或者顯式呼叫

在乙個實際專案中,類和類之間是有可能存在多種關係的,那麼應該如何快速的分析他們之間的關係呢,尤其是在建構函式這方面,我們知道物件建立時建構函式的呼叫順序有如下幾點:

呼叫父類的建構函式

呼叫成員變數的建構函式

呼叫自身的建構函式

所以我們可以形象地將這幾點規則總結為乙個九字口訣:

先父母

後客人再自己

下面我們通過乙個例項來訓練一下對這個口訣的應用。

#include

#include

using

namespace std;

class

object};

class

parent

:public object

//即使是建立物件c1,這裡的初始化列表中也不能少了object(s)的初始化工作,因為這是規則,只要產生了父子類的關係,就會產生對父類建構函式的呼叫,既然父類沒有提供無參建構函式或者預設引數建構函式,那麼編譯器可能就會將它當成是潛在的危險,程式就會報錯,即使使用過程中並沒有呼叫該函式,但是這是書寫的規則。

parent

(string s)

:object

(s)}

;class

child

:public parent

child

(string s)

:parent

(s),

o1(s+

"1"),o2

(s+"2"

)//即使是建立物件c1,這裡的初始化列表中也不能少了o1(s+"1"),o2(s+"2")的初始化工作};

intmain()

執行結果:

分析:此處拿物件c2來做分析,物件c1也是同樣的分析方法。在建立物件c2時,我們先找找物件c2的父母的建構函式,即遵從「」先父母「」原則,然後我們找到了父類parent,這時就應該在child類的有參建構函式那裡的初始化列表中呼叫parent的有參建構函式,然後我們發現他又繼承於類object,所以他又是parent的父類,所以又得往上找父類函式,同理,在parent類的有參建構函式那裡的初始化列表中呼叫object的有參建構函式,因為這時object已經是最頂層的父類了,所以這時我們開始遵循「」後客人「」的原則了,也就是尋找child這個類中的成員變數的建構函式,然後發現這個object是沒有提供無參構造的,那麼這個時候我們就需要在child的初始化列表中呼叫object的建構函式,以免報錯;最後就是遵循「再自己「的原則了,這時就很好理解了,直接呼叫這個類本身的建構函式了。

析構函式的呼叫順序和析構函式相反

執行自身的析構函式

執行成員變數的析構函式

執行父類的析構函式

我們對上面那個程式修改一下,以驗證一下繼承中析構函式的呼叫順序是如何的。

#include

#include

using

namespace std;

class

object

~object()

};class

parent

:public object

parent

(string s)

:object

(s)~

parent()

};class

child

:public parent

child

(string s)

:parent

(s),

o1(s+

"1"),o2

(s+"2")~

child()

};intmain()

執行結果:

分析:只要把九字口訣倒著念就可以了。

繼承中的構造與析構

賦值相容性原則 子類物件可以當作父類物件使用 子類物件可以直接賦值給父類物件 子類物件可以直接初始化父類物件 父類指標可以直接指向子類物件 父類引用可以直接引用子類物件 子類是就是特殊的父類!class child public parent int main int argc,char argv ...

繼承中構造析構

在繼承中面臨乙個問題就是 我們的基類和派生類都有各自的建構函式和析構函式,那麼再例項化派生類成員的時候,這個構造析構的順序是怎麼樣的呢?class animal animal void setm int a 0 intgetage private int age 我們構造了個動物類,我們需要繼續構造...

繼承的構造與析構

子類物件在構造時,先呼叫父類的建構函式,然後再呼叫自己的建構函式,析構順序相反。看下測試 include include using namespace std class grandparent public grandparent cout 輸出結果如下 結果很明顯了,子類構造時,先呼叫父親的建...