自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

分清繼承關(guān)系中基類和子類構(gòu)造函數(shù)調(diào)用順序

開發(fā) 開發(fā)工具
這里將介紹繼承關(guān)系中基類和子類構(gòu)造函數(shù)調(diào)用順序,希望本文能對大家有所幫助。

我們這里將分析一下繼承關(guān)系中基類和子類構(gòu)造函數(shù)調(diào)用順序,希望通過本文,能使大家對于繼承的理解更加深刻。

首先回顧并討論先有雞還是先有蛋的問題在C++中將會是什么情況。如果編寫:

  1. class Egg;  
  2. class Hen  
  3. {  
  4. public:  
  5. int n;  
  6. Egg egg;  
  7.     Hen() {  
  8.         n=5;  
  9.         cout<<"Hen's con "<   
  10.     }  
  11. };  
  12. class Egg : public Hen  
  13. {  
  14. public:  
  15.     int m;  
  16.     Egg(){  
  17.         m=10;  
  18.         cout<<"Egg's con"<   
  19.     }  
  20. };  
  21. int main()  
  22. {  
  23.     Egg dan;  

這在C++中是無法編譯通過的,首先,學(xué)過編譯原理的都應(yīng)該知道,所有語言在編譯的時候都需要確定一個類的大小。C++的編譯器在編譯一個類的時候,需要分析這個類的大小,而sizeof(Egg)=sizeof(Hen)+sizeof(Egg)+…,編譯器無法獲知其大小,自然也無法編譯通過;而JAVA、C#則不同,其類的成員皆為基本類型或引用。同時,和Java、C#等語言不同,C++不能做全局優(yōu)化編譯(即使打開全局優(yōu)化開關(guān)也沒有用),它的編譯是逐步向后的分析方式。C++這樣做,也在編譯時就防止出現(xiàn)先有雞還是先有蛋而產(chǎn)生的矛盾。大家可以嘗試在C++中嘗試其他方法看編譯是否能夠通過。

JAVA雖然可以在Hen類的初始化時對Egg進行構(gòu)造(通過new Egg()),但運行時會出現(xiàn)堆棧溢出的錯誤:

  1. Exception in thread "main" java.lang.StackOverflowError  
  2.     at Egg.(…)  
  3.     at Hen.(…)  
  4.     at Egg.(…)  
  5.     at Hen.(…)  
  6. … 

下面回到本文的主題。我們知道,C++和JAVA不一樣,C++子類是默認(rèn)調(diào)用基類構(gòu)造函數(shù)的,而JAVA則需要super()。為了研究基類和子類構(gòu)造函數(shù)的調(diào)用順序問題,以上述程序為基礎(chǔ),我編寫了這樣一個測試:

  1. class Hen  
  2. {  
  3. public:  
  4.     int n;  
  5.     Hen() {  
  6.         n=5;  
  7.         cout<<"Hen's con "<   
  8.     }  
  9.    Hen(int i) {  
  10.         n=i;  
  11.         cout<<"Hen's con "<   
  12.     }  
  13. };  
  14. class Hen1  
  15. {  
  16. public:  
  17.     int x;  
  18.     Hen1() {  
  19.        x=6;  
  20.         cout<<"Hen1's con "<   
  21.     }  
  22. };  
  23. class Hen2  
  24. {  
  25. public:  
  26.     int y;  
  27.     Hen2() {  
  28.         y=7;  
  29.        cout<<"Hen2's con "<   
  30.     }  
  31. };  
  32. class Egg : public Hen, public Hen2, public Hen1  
  33. {  
  34. public:  
  35.     int m;  
  36.     Hen hen;  
  37.     Hen1 hen1;  
  38.     Hen2 hen2;  
  39.     Egg(int i) : Hen2(),Hen1(),Hen(),hen(i), hen2(), hen1(){  
  40.         m=10;  
  41.         cout<<"Egg's con"<   
  42.     }  
  43. };  
  44. int main()  
  45. {  
  46.     Egg dan(1);  
  47. }  
  48. Output:  
  49. Hen's con 5  
  50. Hen2's con 7  
  51. Hen1's con 6  
  52. Hen's con 1  
  53. Hen1's con 6  
  54. Hen2's con 7  
  55. Egg's con 

通過這段程序可得如下結(jié)論:

1、基類構(gòu)造函數(shù)。如果有多個基類,則構(gòu)造函數(shù)的調(diào)用順序是某類在類繼承表中出現(xiàn)的順序,而不是它們在成員初始化表中的順序。如這里,是按照“class Egg : public Hen, public Hen2, public Hen1”的順序

2、成員類對象構(gòu)造函數(shù)。如果有多個成員類對象,則構(gòu)造函數(shù)的調(diào)用順序是對象在類中被聲明的順序,而不是它們出現(xiàn)在成員初始化表中的順序。如這里,是按照Egg聲明里

Hen hen;

Hen1 hen1;

Hen2 hen2;

的順序。

總1、2而言之,成員初始化表順序?qū)τ跇?gòu)造和賦值順序沒有任何意義

3、成員類對象并不是一開始就被構(gòu)造,再根據(jù)初始化表賦值,而是在調(diào)用構(gòu)造函數(shù)的時候,根據(jù)傳入的參數(shù)根據(jù)成員初始化表中進行一次構(gòu)造,構(gòu)造順序是對象在類中聲明的順序。

【編輯推薦】

  1. C#從C和C++繼承的特點淺談
  2. 實現(xiàn)C#繼承與C#多態(tài)的實例演示
  3. 關(guān)于interface繼承來源的討論
  4. 學(xué)習(xí)C#接口繼承
  5. C#繼承構(gòu)造函數(shù)實現(xiàn)及調(diào)用淺析
責(zé)任編輯:彭凡 來源: 51CTO.com
相關(guān)推薦

2010-01-20 18:06:06

C++虛基類

2013-03-04 11:10:03

JavaJVM

2009-08-13 18:36:36

C#繼承構(gòu)造函數(shù)

2009-10-23 11:31:05

CLR Via C#調(diào)

2009-12-10 13:37:16

PHP parent

2009-06-18 09:51:25

Java繼承

2023-12-07 07:41:15

JavaScript函數(shù)原型

2011-08-24 13:56:27

JavaScript

2009-08-13 18:26:35

C#繼承構(gòu)造函數(shù)

2025-02-07 08:47:38

C#派生類接口

2009-12-11 10:42:00

Scala講座類定義構(gòu)造函數(shù)

2009-12-16 09:43:35

Ruby父類Objec

2009-08-13 18:15:06

C#繼承構(gòu)造函數(shù)

2020-06-17 12:22:44

C覆蓋重載

2022-01-04 19:33:03

Java構(gòu)造器調(diào)用

2009-09-03 13:14:55

C#構(gòu)造函數(shù)C#析構(gòu)函數(shù)

2009-07-31 16:06:50

成員函數(shù)構(gòu)造函數(shù)C#

2009-09-04 11:15:07

選擇C#構(gòu)造函數(shù)

2011-08-08 09:51:52

Cocoa 框架

2009-08-14 09:15:28

C#調(diào)用構(gòu)造函數(shù)
點贊
收藏

51CTO技術(shù)棧公眾號