日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

C++三大继承构造函数的执行顺序详解

發(fā)布時(shí)間:2025/3/15 c/c++ 8 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++三大继承构造函数的执行顺序详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

寫的挺好的,關(guān)于繼承和構(gòu)造函數(shù)的先后順序問題。

?

轉(zhuǎn)自:?http://blog.csdn.net/daheiantian/archive/2011/02/18/6438782.aspx?

?

一、單繼承

核心:在構(gòu)造子類之前一定要執(zhí)行父類的一個(gè)構(gòu)造函數(shù)。

1.構(gòu)造函數(shù)(不包括復(fù)制構(gòu)造函數(shù))。

????????順序:①直接父類;②自己??
????????????注意:若
直接父類還有父類,那么“直接父類的父類”會(huì)在“直接父類” 之前 構(gòu)造。 可以理解為這是一個(gè)遞歸的過程,知道出現(xiàn)一個(gè)沒有父類的類才停止。

????2.1 如果沒有顯式定義構(gòu)造函數(shù),則“合成的默認(rèn)構(gòu)造函數(shù)”會(huì)自動(dòng)調(diào)用直接父類的“默認(rèn)構(gòu)造函數(shù)”,然后調(diào)用編譯器為自己自動(dòng)生成的“合成的默認(rèn)構(gòu)造函數(shù)”。?
????2.2 如果顯式定義了自己的構(gòu)造函數(shù)?
????????2.2.1 如果
沒有顯式調(diào)用直接父類的任意一個(gè)構(gòu)造函數(shù),那么和“合成的默認(rèn)構(gòu)造函數(shù)”一樣,會(huì)先自動(dòng)調(diào)用直接父類的 默認(rèn)構(gòu)造函數(shù),然后調(diào)用自己的構(gòu)造函數(shù)。??
????????2.2.2 如果
顯式調(diào)用直接父類的任意一個(gè)構(gòu)造函數(shù),那么會(huì)先調(diào)用直接父類相應(yīng)的構(gòu)造函數(shù),然后調(diào)用自己的構(gòu)造函數(shù)。

2. 復(fù)制構(gòu)造函數(shù)

???????????順序:①直接父類;②自己?
???????????????注意:和構(gòu)造函數(shù)一樣,若直接父類還有父類,那么“直接父類的父類”會(huì)在“直接父類” 之前 構(gòu)造。 可以理解為這是一個(gè)
遞歸的過程,知道出現(xiàn)一個(gè)沒有父類的類才停止。

????2.1 如果?沒有顯式定義復(fù)制構(gòu)造函數(shù),則“合成的復(fù)制構(gòu)造函數(shù)”會(huì)自動(dòng)調(diào)用直接父類的“復(fù)制構(gòu)造函數(shù)”,然后調(diào)用編譯器為自己自動(dòng)生成的“合成的復(fù)制構(gòu)造函數(shù)”(注意:不是默認(rèn)構(gòu)造函數(shù))??
????2.2 如果顯式定義了自己的復(fù)制構(gòu)造函數(shù) (和構(gòu)造函數(shù)類似)?
????????2.2.1 如果
沒有顯式調(diào)用父類的任意一個(gè)構(gòu)造函數(shù),那么會(huì)先調(diào)用直接父類的 默認(rèn)構(gòu)造函數(shù)(注意:不是 復(fù)制構(gòu)造函數(shù))。?
????????2.2.2 如果
顯式調(diào)用直接父類的任意一個(gè)構(gòu)造函數(shù),那么會(huì)先調(diào)用直接父類相應(yīng)的構(gòu)造函數(shù)。

3.賦值操作符重載

????3.1 如果沒有顯式定義,會(huì)自動(dòng)調(diào)用直接父類賦值操作符。(注意:不是 默認(rèn)構(gòu)造函數(shù))???
????3.2 如果
顯式定義了,就只執(zhí)行自己定義的版本,不再自動(dòng)調(diào)用直接父類的賦值操作符,只執(zhí)行自己的賦值操作符。?
????????????注意:如有需要對(duì)父類子部分進(jìn)行賦值,應(yīng)該在自己編寫的代碼中,顯式調(diào)用父類的賦值操作符。?
4. 析構(gòu)函數(shù)??
????與構(gòu)造函數(shù) 順序相反。

二、多繼承

繼承的差別就是:需要考慮到多個(gè)直接父類。其它的都相同

1.構(gòu)造函數(shù)(不包括復(fù)制構(gòu)造函數(shù))。

???????????????順序:①所有直接父類;(按照基類繼承列表中聲明的順序)②自己??
????????????注意:若
直接父類還有父類,那么“直接父類的父類”會(huì)在“直接父類” 之前 構(gòu)造。 可以理解為這是一個(gè)遞歸的過程,知道出現(xiàn)一個(gè)沒有父類的類才停止。

????2.1 如果?沒有 顯式定義構(gòu)造函數(shù),則“合成的默認(rèn)構(gòu)造函數(shù)”會(huì)自動(dòng)依次調(diào)用所有直接父類的“默認(rèn)構(gòu)造函數(shù)”,然后調(diào)用編譯器為自己自動(dòng)生成的“合成的默認(rèn)構(gòu)造函數(shù)”。?
????2.2 如果顯式定義了自己的構(gòu)造函數(shù)?
????????2.2.1 如果沒有顯式調(diào)用父類的任意一個(gè)構(gòu)造函數(shù),那么和“合成的默認(rèn)構(gòu)造函數(shù)”一樣,會(huì)自動(dòng)依次調(diào)用
所有直接父類的 默認(rèn)構(gòu)造函數(shù),然后調(diào)用自己的構(gòu)造函數(shù)。?
????????2.2.2 如果顯式調(diào)用了父類的任意一個(gè)構(gòu)造函數(shù),那么按照基類列表的順序,對(duì)于每一個(gè)父類依次判斷:若顯式調(diào)用了構(gòu)造函數(shù),那么會(huì)調(diào)用該
父類相應(yīng)的構(gòu)造函數(shù);如果沒有顯式調(diào)用,就調(diào)用默認(rèn)構(gòu)造函數(shù)。最后調(diào)用自己的構(gòu)造函數(shù)。

2. 復(fù)制構(gòu)造函數(shù)

???????????????順序:①所有直接父類;(按照基類繼承列表中聲明的順序)②自己??
????????????注意:和構(gòu)造函數(shù)一樣,若
直接父類還有父類,那么“直接父類的父類”會(huì)在“直接父類” 之前 構(gòu)造。 可以理解為這是一個(gè)遞歸的過程,知道出現(xiàn)一個(gè)沒有父類的類才停止。

????2.1 如果?沒有顯式定義復(fù)制構(gòu)造函數(shù),則“合成的復(fù)制構(gòu)造函數(shù)”會(huì)自動(dòng)依次調(diào)用所有直接父類的“復(fù)制構(gòu)造函數(shù)”,然后調(diào)用編譯器為自己自動(dòng)生成的“合成的復(fù)制構(gòu)造函數(shù)”(注意:不是默認(rèn)構(gòu)造函數(shù))?
????2.2 如果顯式定義了自己的復(fù)制構(gòu)造函數(shù) (和構(gòu)造函數(shù)類似)?
????????2.2.1 如果沒有顯式調(diào)用父類的任意一個(gè)構(gòu)造函數(shù),那么會(huì)先自動(dòng)依次調(diào)用
直接父類的 默認(rèn)構(gòu)造函數(shù)(注意:不是 復(fù)制構(gòu)造函數(shù))。?
????????2.2.2 如果
顯式調(diào)用直接父類的任意一個(gè)構(gòu)造函數(shù),那么按照基類列表的順序,對(duì)于每一個(gè)父類依次判斷:若顯式調(diào)用了構(gòu)造函數(shù),那么會(huì)調(diào)用該父類相應(yīng)的構(gòu)造函數(shù);如果沒有顯式調(diào)用,就調(diào)用默認(rèn)構(gòu)造函數(shù)。最后調(diào)用自己的復(fù)制構(gòu)造函數(shù)。

3.賦值操作符重載

????3.1 如果沒有顯式定義,會(huì)自動(dòng)依次調(diào)用直接父類賦值操作符。(注意:不是 默認(rèn)構(gòu)造函數(shù))?
????3.2 如果
顯式定義了,就只執(zhí)行自己定義的版本,不再自動(dòng)調(diào)用直接父類的賦值操作符,只執(zhí)行自己的賦值操作符。??
????????????注意:如有需要對(duì)父類子部分進(jìn)行賦值,應(yīng)該在自己編寫的代碼中,
顯式調(diào)用所有直接父類的賦值操作符。?
4. 析構(gòu)函數(shù)??
????與 構(gòu)造函數(shù) 順序相反。

三、虛繼承

繼承的差別就是:要考慮到虛基類,其它的都相同。(虛基類的初始化要早于非虛基類,并且只能由子類對(duì)其進(jìn)行初始化)

1.構(gòu)造函數(shù)(不包括復(fù)制構(gòu)造函數(shù))。

????????????????????????????????順序:①所有虛基類(按照基類繼承列表中聲明的順序進(jìn)行查找);②所有直接父類;(按照基類繼承列表中聲明的順序)③自己??
????????????注意:若
虛基類或者直接父類還有父類,那么“直接父類的父類”會(huì)在“直接父類” 之前 構(gòu)造,“虛基類的父類”也會(huì)在“虛基類”之前構(gòu)造。 可以理解為這是一個(gè)遞歸的過程,知道出現(xiàn)一個(gè)沒有父類的類才停止。

????2.1 如果?沒有 顯式定義構(gòu)造函數(shù),則“合成的默認(rèn)構(gòu)造函數(shù)”會(huì)先依次調(diào)用所有虛基類的默認(rèn)構(gòu)造函數(shù),然后再自動(dòng)依次調(diào)用所有直接父類的“默認(rèn)構(gòu)造函數(shù)”,最后調(diào)用編譯器為自己自動(dòng)生成的“合成的默認(rèn)構(gòu)造函數(shù)”。?
????2.2 如果顯式定義了自己的構(gòu)造函數(shù)?????????2.2.1 如果沒有顯式調(diào)用父類的任意一個(gè)構(gòu)造函數(shù),那么和“合成的默認(rèn)構(gòu)造函數(shù)”一樣,會(huì)先依次調(diào)用
所有虛基類的默認(rèn)構(gòu)造函數(shù),然后再自動(dòng)依次調(diào)用所有直接父類的 默認(rèn)構(gòu)造函數(shù),最后調(diào)用自己的構(gòu)造函數(shù)。?
????????2.2.2 如果顯式調(diào)用了父類的任意一個(gè)構(gòu)造函數(shù),那么按照基類列表的順序,先初始化所有虛基類,再初始化所有直接父類。對(duì)于每一個(gè)父類依次判斷:若顯式調(diào)用了構(gòu)造函數(shù),那么會(huì)調(diào)用該
父類相應(yīng)的構(gòu)造函數(shù);如果沒有顯式調(diào)用,就調(diào)用默認(rèn)構(gòu)造函數(shù)。最后調(diào)用自己的構(gòu)造函數(shù)。

2. 復(fù)制構(gòu)造函數(shù)

???????????????????????????????順序:①所有虛基類(按照基類繼承列表中聲明的順序進(jìn)行查找);②所有直接父類;(按照基類繼承列表中聲明的順序)③自己??
????????????注意:和構(gòu)造函數(shù)一樣,若
虛基類或者直接父類還有父類,那么“直接父類的父類”會(huì)在“直接父類” 之前 構(gòu)造,“虛基類的父類”也會(huì)在“虛基類”之前構(gòu)造。 可以理解為這是一個(gè)遞歸的過程,知道出現(xiàn)一個(gè)沒有父類的類才停止。

????2.1 如果?沒有顯式定義復(fù)制構(gòu)造函數(shù),則“合成的復(fù)制構(gòu)造函數(shù)”會(huì)自動(dòng)依次調(diào)用所有直接父類的“復(fù)制構(gòu)造函數(shù)”,然后調(diào)用編譯器為自己自動(dòng)生成的“合成的復(fù)制構(gòu)造函數(shù)”(注意:不是默認(rèn)構(gòu)造函數(shù))?
????2.2 如果顯式定義了自己的復(fù)制構(gòu)造函數(shù) (和構(gòu)造函數(shù)類似)?
????????2.2.1 如果沒有顯式調(diào)用父類的任意一個(gè)構(gòu)造函數(shù),那么會(huì)先依次調(diào)用
所有虛基類的默認(rèn)構(gòu)造函數(shù),然后再依次調(diào)用所有直接父類的 默認(rèn)構(gòu)造函數(shù)(注意:不是 復(fù)制構(gòu)造函數(shù))。?
????????2.2.2 如果
顯式調(diào)用直接父類的任意一個(gè)構(gòu)造函數(shù),那么按照基類列表的順序,先初始化所有虛基類,再初始化所有直接父類。對(duì)于每一個(gè)父類依次判斷:若顯式調(diào)用了構(gòu)造函數(shù),那么會(huì)調(diào)用該父類相應(yīng)的構(gòu)造函數(shù);如果沒有顯式調(diào)用,就調(diào)用默認(rèn)構(gòu)造函數(shù)。

3.賦值操作符重載

????3.1 如果沒有顯式定義,會(huì)自動(dòng)依次調(diào)用所有虛基類所有直接父類賦值操作符。(注意:不是 默認(rèn)構(gòu)造函數(shù))?
?????????????3.2 如果
顯式定義了,就只執(zhí)行自己定義的版本,不再自動(dòng)調(diào)用直接父類的賦值操作符,只執(zhí)行自己的賦值操作符。??
????????????注意:如有需要對(duì)父類子部分進(jìn)行賦值,應(yīng)該在自己編寫的代碼中,
顯式調(diào)用所有虛基類所有直接父類的賦值操作符。?
4. 析構(gòu)函數(shù)??
????與 構(gòu)造函數(shù) 順序相反。

四、總結(jié):

1.?整體順序:虛基類??-->??直接父類??-->自己

2. 在任何顯式定義的構(gòu)造函數(shù)中,如果沒有顯式調(diào)用父類的構(gòu)造函數(shù),那么就會(huì)調(diào)用父類的默認(rèn)構(gòu)造函數(shù)。

3.?合成的復(fù)制構(gòu)造函數(shù)合成的賦值操作符,(當(dāng)沒有顯式定義時(shí),編譯器自動(dòng)提供),會(huì)自動(dòng)調(diào)用的是虛基類直接父類的復(fù)制構(gòu)造函數(shù)和賦值操作符,而不是默認(rèn)構(gòu)造函數(shù);

4. 自己顯式定義的復(fù)制構(gòu)造函數(shù),除非在初始化列表中顯示調(diào)用,否則只會(huì)調(diào)用虛基類和父類的默認(rèn)構(gòu)造函數(shù)。

5. 自己顯式定義的賦值操作符,除非顯式調(diào)用,否則只執(zhí)行自己的代碼。

6. 析構(gòu)函數(shù)的執(zhí)行順序與 構(gòu)造函數(shù) 相反。

總結(jié)

以上是生活随笔為你收集整理的C++三大继承构造函数的执行顺序详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。