class Base { public: Base() { cout << "Base構造函數!" << endl; } ~Base() { cout << "Base析構函數!" << endl; } }; class Son : public Base { public: Son() { cout << "Son構造函數!" << endl; } ~Son() { cout << "Son析構函數!" << endl; } }; void test01() { //繼承中 先調用父類構造函數,再調用子類構造函數,析構順序與構造相反 Son s; } int main() { test01(); system("pause"); return 0; }
運行結果:
總結:繼承中 先調用父類構造函數,再調用子類構造函數,析構順序與構造相反
重點:
父類構造函數的調用規則:
①. 如果子類沒有定義構造函數,則調用父類的無參數的構造函數;
②. 如果子類定義了構造函數,不論是無參數還是帶參數,在創建子類的對象的時候,首先執行父類無參數的構造函數,然后執行自己的構造函數;
③. 在創建子類對象時候,如果子類的構造函數沒有顯示調用父類的構造函數,則會調用父類的默認無參構造函數;
④. 在創建子類對象時候,如果子類的構造函數沒有顯示調用父類的構造函數且父類自己提供了無參構造函數,則會調用父類自己的無參構造函數;
⑤. 在創建子類對象時候,如果子類的構造函數沒有顯示調用父類的構造函數且父類只定義了自己的有參構造函數,則會出錯(如果父類只有有參數的構造函數,則子類必須顯示調用此帶參構造函數);
以上總結起來就兩句話:
如果子類沒有顯示的調用父類的構造函數,那么默認會調用父類無參的構造函數!!!
如果父類只提供了有參數的構造函數,那么子類在默認情況下調用父類的無參構造函數時就會報錯!(那么解決這個報錯,需要給子類加上調用父類有參構造函數的通知即可)
報錯:
#include <iostream> using namespace std; class Base { public: Base(int argue) { cout << "我是Base有參構造函數!"<<argue << endl; } ~Base() { cout << "Base析構函數!" << endl; } }; class Son : public Base { public: Son()//因為創建子類時系統默認調用父類無參構造函數,但是父類中只有有參構造函數,所以會報錯 { cout << "Son構造函數!" << endl; } ~Son() { cout << "Son析構函數!" << endl; } }; void test01() { //繼承中 先調用父類構造函數,再調用子類構造函數,析構順序與構造相反 Son s; } int main() { test01(); //system("pause"); return 0; }
運行結果報錯:
修改后:
class Base { public: Base(int argue) { cout << "我是Base有參構造函數!"<<argue << endl; } ~Base() { cout << "Base析構函數!" << endl; } }; class Son : public Base { public: Son():Base(666)//修改系統默認調用無參為有參 { cout << "Son構造函數!" << endl; } ~Son() { cout << "Son析構函數!" << endl; } }; void test01() { //繼承中 先調用父類構造函數,再調用子類構造函數,析構順序與構造相反 Son s; } int main() { test01(); system("pause"); return 0; }
運行結果: