幾個問題
一個類的各資料成員的構造順序?
按他們在類定義中出現的先後順序:先定義者先構造。
類的對象成員的構造函數與類自身的構造函數的執行順序?
先執行對象成員的構造函數,再執行類自身的構造函數。
構造順序與析構順序的關系?
二者順序相反:先構造者,後析構。
構造函數和析構函數用來建立和釋放該類的對象,當這個類是派生類時,其對象的建立和釋放應與其基類對象及成員對象相聯系。
在聲明派生類時,一般還應當自己定義派生類的構造函數和析構函數,因為構造函數和析構函數是不能從基類繼承的

派生類對象的建立和初始化與基類對象的建立和初始化有關。即構造派生類對象時,要對其基類資料成員、所含對象成員的資料成員以及其他的新增資料成員一起進行初始化。這種初始化工作是由派生類的構造函數來完成的。
派生類成員包括兩部分:
(1)從基類繼承的成員:由基類構造函數完成
(2)自身定義的成員: 由派生類構造函數完成
在派生類中,構造基類資料成員的可能方式:
方式一,在派生類中直接對基類型資料成員初始化:
class BC
{
public:
BC( )
{
x = y = -1;
}
private:
int x, y;
};
class DC : public BC
{
public:
DC( )
{
x = y = -1;//錯誤,不能構造基類的私有成員 error C2248: “B::x”: 無法通路 private 成員(在“B”類中聲明)
}
private:
string S;
};
方式二,顯示調用基類構造函數
class BC
{
public:
BC( )
{
x = y = -1;
}
private:
int x, y;
};
class DC : public BC
{
public:
DC( )
{
BC( );//這是構造後才調用,語義錯誤
}
private:
string S;
};
這樣的程式可以編譯通過,但語意錯誤,這是派生類先構造後,在調用基類的構成函數。
正确構成基類資料成員的方式為:
class BC
{
public:
BC( )
{
x = y = -1;
}
private:
int x, y;
};
class DC : public BC
{
public:
DC( ) : BC( ), S("派生類"), { }//初始化清單
private:
string S;
};
在建立派生類的對象時,需要調用基類的構造函數:初始化派生類對象從基類繼承的成員。在執行一個派生類的構造函數之前,總是先執行基類的構造函數。
調用基類構造函數的兩種方式:
(1)顯式方式:在派生類的構造函數中,通過參數化表為基類的構造函數提供參數
derived::derived(arg_derived-list):base(arg_base-list)
(2)隐式方式:在派生類/基類的構造函數都預設時,派生類的構造函數則自動調用基類的預設構造函數。
在一個多層次的繼承層次結構中,一個派生類對象的建立時,其構造函數的調用有點類似于多米諾骨牌效應 (domino effect)
列出了不同情況下的派生類構造函數要求:
上面的例子其實也很好了解,我們知道:在執行一個派生類的構造函數之前,總是先執行基類的構造函數。
1.如果基類中無構造函數,那麼對于派生類來說,不管派生類是何種構造函數,編譯器都會先調用的執行基類的預設構造函數,然後再執行派生類的構造函數。
2.如果基類是一個無預設參數的構造函數,那麼對于派生類一旦沒有構造函數,那麼就不會自動的先構造基類的構造函數,這是不允許的。
3.如果基類中有預設參數的構造函數B(),那麼派生類中沒有構造函數也是允許的,編譯器會自動調用。
通常, 一個基類有一個預設構造函數。
以下做法是有其實際意義的:當一個派生類對象被建立時會引起某個基類的構造函數的執行。
(這條建議在派生類新增成員依賴于基類成員時展現非常明顯)
class Team
{
public:
Team(int len =100)
{
names = new string[maxno = len ];
//基類構造函數完成其成員初始化,供派生類構造使用。
}
protected:
string* names;
int maxno;
};
class BaseballTeam : public Team
{
public:
BaseballTeam(const string s[], int si)
: Team(si)//為支援派生類構造本意,必須明确調用基類構造函數。
{
for(int i=0; i<si; i++)
names[i] = s[i];
//派生類構造函數執行前,基類構造必須完成。
}
};
執行構造函數的順序:
1. 基類的構造函數
2. 子對象的構造函數
3. 其他資料成員初始化
繼承下的析構函數 Destructors Under Inheritance
class BC
{
public:
BC( )
{
sBC = new char[3];
cout << "BC allocates 3 bytes.\n";
}
~BC( )
{
delete [ ] sBC;
cout << "BC free 3 bytes.\n";
}
private:
char* sBC;
};
class DC : public BC
{
public:
DC( )
{
sDC = new char[5];
cout << "DC allocates 5 bytes.\n";
}
~DC( )
{
delete [ ] sDC;
cout << "DC free 5 bytes.\n";
}
private:
char* sDC;
};
int main( )
{
DC d;
cout << “-------” << endl;
return 0;
}
作者:王陸
出處:https://www.cnblogs.com/wkfvawl/
-------------------------------------------
個性簽名:罔談彼短,靡持己長。做一個謙遜愛學的人!
本站使用「署名 4.0 國際」創作共享協定,轉載請在文章明顯位置注明作者及出處。鑒于部落客處于考研複習期間,有什麼問題請在評論區中提出,部落客盡可能當天回複,加微信好友請注明原因