php 派生类 构造,C++派生类的构造函数和析构函数
派生類對象中包含基類對象,因此派生類對象在創建時,除了要調用自身的構造函數進行初始化外,還要調用基類的構造函數初始化其包含的基類對象。因此,程序中任何能夠生成派生類對象的語句,都要說明其包含的基類對象是如何初始化的。
如果對此不做說明,則編譯器認為基類對象要用無參構造函數初始化——如果基類沒有無參構造函數,則會導致編譯錯誤。
在執行一個派生類的構造函數之前,總是先執行基類的構造函數。
和封閉類說明成員對象如何初始化類似,派生類說明基類對象如何初始化,也需要在構造函數后面添加初始化列表。在初始化列表中,要指明調用基類構造函數的形式。具體寫法如下:
構造函數名(形參表): 基類名(基類構造函數實參表)
{
...
}
派生類對象消亡時,先執行派生類的析構函數,再執行基類的析構函數。
下面的程序演示了派生類的構造函數和析構函數的調用順序:
#include
#include
using namespace std;
class CBug {
int legNum, color;
public:
CBug(int ln, int c1) : legNum(ln), color(c1)
{
cout << "CBug Constructor" << endl;
};
~CBug()
{
cout << "CBug Destructor" << endl;
}
void Printlnfo()
{
cout << legNum << "," << color << endl;
}
};
class CFlyingBug : public CBug
{
int wingNum;
public:
//CFlyingBug(){} 若不注釋掉則會編譯出錯
CFlyingBug::CFlyingBug(int ln, int c1, int wn) : CBug(ln, c1), wingNum(wn)
{
cout << "CFlyingBug Constructor" << endl;
}
~CFlyingBug()
{
cout << "CFlyingBug Destructor" << endl;
}
};
int main() {
CFlyingBug fb(2, 3, 4);
fb.Printlnfo();
return 0;
}
程序輸出結果:
CBug Constructor
CFlyingBug Constructor
2,3
CFlyingBug Destructor
CBug Destructor
第 25 行如果沒有注釋掉會編譯出錯。因為這個構造函數沒有說明在派生類對象用該構造函數初始化的情況下,其基類對象該如何初始化——這也就意味著基類對象應該用無參構造函數初始化,可是 CBug 類并沒有無參構造函數,所以編譯會出錯。
第 26 行中的“CBUg(ln, c1)”指明了在派生類對象用該構造函數初始化的情況下,其基類對象的初始化方式。
思考題:派生類對象生成時要先執行基類構造函數,消亡時要先執行自身析構函數,再執行基類析構函數,為什么?
和封閉類的情況類似,如果一個派生類對象是用默認復制構造函數初始化的,那么它內部包含的基類對象也要用基類的復制構造函數初始化。
多層次的派生
在 C++ 中,派生可以是多層次的。例如學生類派生出中學生類,中學生類又派生出初中生類和高中生類。總之,類 A 派生類 B,類 B 可再派生類 C,類 C 又能派生類 D,以此類推。
這種情況下,稱類 A 是類 B 的直接基類,類 B 是類 C 的直接基類,類 A 是類 C 的間接基類。當然,類 A 也是類 D 的間接基類。在定義派生類時,只寫直接基類,不寫間接基類。派生類沿著類的層次自動向上繼承它所有的間接基類。
派生類的成員包括派生類自己定義的成員、直接基類中定義的成員,以及所有間接基類的全部成員。
當派生類的對象生成時,會從最頂層的基類開始逐層往下執行所有基類的構造函數,最后再執行自身的構造函數;當派生類對象消亡時,會先執行自身的析構函數,然后從底向上依次執行各個基類的析構函數。
例如下面的程序:
#include
using namespace std;
class A {
public:
int n;
A(int i) :n(i) { cout << "A " << n << " constructed" << endl; }
~A() { cout << "A " << n << " destructed" << endl; }
};
class B :public A
{
public:
B(int i) :A(i) { cout << "B constructed" << endl; }
~B() { cout << "B destructed" << endl; }
};
class C :public B {
public:
C() :B(2) { cout << "B constructed" << endl; }
~C() { cout << "B destructed" << endl; }
};
int main()
{
C Obj;
return 0;
}
程序的輸出結果:
A 2 constructed
B constructed
B constructed
B destructed
B destructed
A 2 destructed
包含成員對象的派生類
在派生類也是封閉類的情況下,構造函數的初始化列表不但要指明基類對象的初始化方式,還要指明成員對象的初始化方式。
派生類對象生成時,會引發一系列構造函數調用,順序是:先從上至下執行所有基類的構造函數,再按照成員對象的定義順序執行各個成員對象的構造函數,最后執行自身的構造函數;而派生類對象消亡時,先執行自身的析構函數,然后按與構造的次序相反的順序依次執行所有成員對象的析構函數,最后再從底向上依次執行各個基類的析構函數。
總結
以上是生活随笔為你收集整理的php 派生类 构造,C++派生类的构造函数和析构函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梨干的功效与作用、禁忌和食用方法
- 下一篇: 紫菜苔的功效与作用、禁忌和食用方法