思考:
如何初始化父類成員?
父類建構函式和子類建構函式有什麼關係?
子類物件的構造
- 子類物件可以定義建構函式
子類建構函式
必須對繼承而來的成員進行初始化
- 直接通過初始化列表或者賦值的方式進行初始化
- 呼叫父類建構函式進行初始化
父類建構函式在子類中的呼叫方式
預設呼叫
- 適用於無參建構函式和使用預設引數的建構函式
顯示呼叫
- 通過初始化列表進行呼叫
- 使用於所有父類建構函式
- 父類建構函式的呼叫
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
子類物件中的構造
構造規則
- 子類物件在建立是會首先呼叫父類的建構函式
- 先執行父類建構函式再執行子類的建構函式
- 父類建構函式可以被隱式呼叫或者顯示呼叫
物件建立時建構函式的呼叫順序
- 呼叫父類的建構函式
- 呼叫成員變數的建構函式
- 呼叫類自身的建構函式
口訣心法: 先父母,後客人,再自己
程式設計實驗: 子類構造深度解析
#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
子類物件的析構
解構函式的呼叫順序與建構函式相反
- 執行自身的解構函式
- 執行成員變數的解構函式
- 執行父類的解構函式
程式設計實驗: 物件的析構
#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
小結
- 子類物件在建立時需要呼叫父類建構函式進行初始化
- 先執行父類建構函式然後執行成員的建構函式
- 父類建構函式顯示呼叫需要在初始化列表中進行
- 子類物件在銷燬時需要呼叫父類解構函式進行處理
以上內容參考狄泰軟體學院系列課程,請大家保護原創!