子類構造函數初始化及父類構造初始化


原創帖子見:https://blog.csdn.net/sevenjoin/article/details/82222895

我們知道,構造方法是用來初始化類對象的。如果在類中沒有顯式地聲明構造函數,那么編譯器會自動創建一個默認的構造函數;並且這個默認的構造函數僅僅在沒有顯式地聲明構造函數的情況下才會被創建創建。

       構造函數與父類的其它成員(成員變量和成員方法)不同,它不能被子類繼承。因此,在創建子類對象時,為了初始化從父類中繼承來的成員變量,編譯器需要調用其父類的構造函數。如果子類的構造函數沒有顯示地調用父類的構造函數,則默認調用父類的無參構造函數,至於什么事顯式調用,在下面會詳細說明!關於子類中構造函數的構造原則,總結如下,歡迎大家指導與批評。

         1.父類沒有聲明構造函數

         (1)子類也沒有聲明自己的構造函數,則父類和子類均由編譯器生成默認的構造函數。

         (2)子類中聲明了構造函數(無參或者帶參),則子類的構造函數可以寫成任何形式,不用顧忌父類的構造函數。在創建子類對象時,先調用父類默認的構造函數(編譯器自動生成),再調用子類的構造函數。

         2.父類只聲明了無參構造函數

         如果子類的構造函數沒有顯式地調用父類的構造,則將會調用父類的無參構造函數。也就是說,父類的無參構造函數將會被隱式地調用。

         3.父類只聲明了帶參構造函數

         在這種情況下,要特別注意。因為父類只有帶參的構造函數,所以如果子類中的構造函數沒有顯示地調用父類的帶參構造函數,則會報錯,所以必需顯示地調用。

關於構造函數的顯示調用,參見下例。

 1 class animal
 2 {
 3 protected:       //成員變量,聲明為protected或者public,這里選擇protected
 4     int height;  //若聲明為private,則不能被子類繼承訪問,會報錯
 5     int weight;
 6 public:
 7     animal(int height,int weight)   //帶參的構造函數
 8     {
 9         this->height=height;
10         this->weight=weight;
11         cout<<"animal的帶參構造函數被調用"<<endl;
12     }
13     virtual ~animal()
14     {
15         cout<<"animal的析構函數被調用"<<endl;
16     }
17 };
18 //子類
19 class fish:public animal
20 {
21 public:
22     fish():animal(height,weight) //顯示調用父類的構造函數
23     {
24         cout<<"fish的構造函數被調用"<<endl;
25     }
26     virtual ~fish()
27     {
28         cout<<"fish的析構函數被調用"<<endl;
29     }
30 };

在子類fish的構造函數中,加上一個冒號(:),然后加上父類的帶參構造函數,這就是父類構造函數的顯式調用。這樣,在子類的構造函數被調用時,系統就會去調用父類的帶參構造函數,從而實現初始化父類的成員變量。運行結果如下:

 

注意:

如果父類只有帶參的構造函數,且該帶參的構造函數的參數有默認值,此時在子類中也可以不用顯示的調用父類的構造函數。

// 父類的構造函數,改成帶有默認值的參數, 這樣在子類中就可以不用顯示調用了
        animal(int height=19 ,int weight=20)   //帶參的構造函數
        {
                this->height=height;
                this->weight=weight;
                cout<<"animal的帶參構造函數被調用"<<endl;
        }

4.父類同時聲明了無參和帶參構造函數

         在這種情況下,子類只需要實現父類的一個構造函數即可,不管是無參的還是帶參的構造函數。如果子類的構造函數沒有顯示地調用父類的構造函數(無參或帶參),則默認調用父類的無參構造函數。

 1 //父類
 2 class animal
 3 {
 4 protected:       //成員變量,聲明為protected或者public,這里選擇protected
 5     int height;  //若聲明為private,則不能被子類繼承訪問,會報錯
 6     int weight;
 7 public:    
 8     animal()
 9     {
10         height=0;
11         weight=0;
12         cout<<"animal的無參構造函數被調用"<<endl;
13     }
14     animal(int height,int weight)   //帶參的構造函數
15     {
16         this->height=height;
17         this->weight=weight;
18         cout<<"animal的帶參構造函數被調用"<<endl;
19     }
20     virtual ~animal()
21     {
22         cout<<"animal的析構函數被調用"<<endl;
23     }
24 };
25 //子類
26 class fish:public animal
27 {
28 public:
29     fish()     //沒有顯示地調用父類的構造函數(無參或帶參),則默認調用父類的無參構造函數
30     {
31         cout<<"fish的構造函數被調用"<<endl;
32     }
33     virtual ~fish()
34     {
35         cout<<"fish的析構函數被調用"<<endl;
36     }
37 };

執行結果:

 

 總結以上幾條,可以歸納出C++中子類繼承父類時構造函數的寫法的規律:當父類有顯式地聲明了構造函數時,子類最低限度的實現父類中的一個(當你需要初始化子類的時候,需要先初始化父類)當父類沒有聲明構造函數時,子類會調用父類的default構造函數。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM