【C++】 46_繼承中的構造與析構

思考:
如何初始化父類成員?
父類構造函數和子類構造函數有什麼關係?ios

子類對象的構造

  • 子類對象能夠定義構造函數
  • 子類構造函數編程

    • 必須對繼承而來的成員進行初始化函數

      • 直接經過初始化列表或者賦值的方式進行初始化
      • 調用父類構造函數進行初始化

  • 父類構造函數在子類中的調用方式spa

    • 默認調用code

      • 適用於無參構造函數和使用默認參數的構造函數
    • 顯示調用對象

      • 經過初始化列表進行調用
      • 使用於全部父類構造函數

  • 父類構造函數的調用
class Child : public Parent
{
public:
    Child()                                         // 隱式調用
    {
        cout << "Child" << endl;
    }
    Child(string s) : Parent(Parameter to Parent)   // 顯示調用
    {
        cout << "Parent" << s << endl;
    }
}

編程實驗: 子類的構造初探

#include <iostream>

using namespace std;

class Parent
{
public:
    Parent()
    {
        cout << "Parent()" << endl; 
    }
    Parent(string s)
    {
        cout << "Parent(string s) : " << s << endl;
    }
};

class Child : public Parent
{
public:
    Child()                              // 隱式調用父類構造函數
    {
        cout << "Child()" << endl;
    }
    Child(string s) : Parent(s)          // 顯示調用父類構造函數
    {
        cout << "Child(string s) : " << s << endl;
    }
};

int main()
{
    Child c;
    Child cc("cc");

    return 0;
}
輸出:
Parent()
Child()
Parent(string s) : cc
Child(string s) : cc

子類對象中的構造

  • 構造規則繼承

    • 子類對象在建立是會首先調用父類的構造函數
    • 先執行父類構造函數再執行子類的構造函數
    • 父類構造函數能夠被隱式調用或者顯示調用

  • 對象建立時構造函數的調用順序string

    1. 調用父類的構造函數
    2. 調用成員變量的構造函數
    3. 調用類自身的構造函數

口訣心法: 先父母,後客人,再本身io

編程實驗: 子類構造深度解析

#include <iostream>
#include <string>

using namespace std;

class Object
{
public:
    Object(string s)
    {
        cout << "Object(string s) : " << s << endl;
    }
};

class Parent : public Object
{
public:
    Parent() : Object("Default")
    {
        cout << "Parent()" << endl; 
    }
    Parent(string s) : Object(s)
    {
        cout << "Parent(string s) : " << s << endl;
    }
};

class Child : public Parent
{
private:
    Object mO1;
    Object mO2;
public:
    Child() : mO1("Default 1"), mO2("Default 2") 
    {
        cout << "Child()" << endl;
    }
    Child(string s) : Parent(s), mO1(s + "1"), mO2(s + "2") 
    {
        cout << "Child(string s) : " << s << endl;
    }
};

int main()
{
    Child cc("cc");

    return 0;
}
輸出:
Object(string s) : cc
Parent(string s) : cc
Object(string s) : cc1
Object(string s) : cc2
Child(string s) : cc

子類對象的析構

  • 析構函數的調用順序與構造函數相反class

    • 執行自身的析構函數
    • 執行成員變量的析構函數
    • 執行父類的析構函數

編程實驗: 對象的析構

#include <iostream>
#include <string>

using namespace std;

class Object
{
private: 
    string ms;
public:
    Object(string s)
    {
        cout << "Object(string s) : " << s << endl;
        ms = s;
    }
    ~Object()
    {
        cout << "~Object() : " << ms << endl;
    }
};

class Parent : public Object
{
private:
    string ms;
public:
    Parent() : Object("Default")
    {
        cout << "Parent()" << endl; 
        ms = "Default";
    }
    Parent(string s) : Object(s)
    {
        cout << "Parent(string s) : " << s << endl;
        ms = s;
    }
    ~Parent()
    {
        cout << "~Parent() : " << ms << endl;
    }
};

class Child : public Parent
{
private:
    Object mO1;
    Object mO2;
    string ms;
public:
    Child() : mO1("Default 1"), mO2("Default 2") 
    {
        cout << "Child()" << endl;
        ms = "Default";
    }
    Child(string s) : Parent(s), mO1(s + "1"), mO2(s + "2") 
    {
        cout << "Child(string s) : " << s << endl;
        ms = s; 
    }
    ~Child()
    {
        cout << "~Child() : " << ms << endl;
    }
};

int main()
{
    Child cc("cc");
    
    cout << endl;

    return 0;
}
輸出:
Object(string s) : cc
Parent(string s) : cc
Object(string s) : cc1
Object(string s) : cc2
Child(string s) : cc

~Child() : cc
~Object() : cc2
~Object() : cc1
~Parent() : cc
~Object() : cc

小結

  • 子類對象在建立時須要調用父類構造函數進行初始化
  • 先執行父類構造函數而後執行成員的構造函數
  • 父類構造函數顯示調用須要在初始化列表中進行
  • 子類對象在銷燬時須要調用父類析構函數進行處理

以上內容參考狄泰軟件學院系列課程,請你們保護原創!

相關文章
相關標籤/搜索