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