在說建構函式之前我們得先弄明白幾個問題,首先是什麼是類的建構函式,什麼是類的成員物件,什麼是基類,然後我們再來說建構函式的呼叫順序。
1、 類的建構函式
建構函式的功能主要用於在類的物件建立時定義初始化的狀態。它沒有返回值,也不能用void來修飾,這就保證了它不僅什麼也不用自動返回,而且根本不能有任何選擇。建構函式不能被直接呼叫,必須通過new運算子在建立物件時才會自動呼叫,一般方法在程式執行到它的時候被呼叫。乙個類可以有多個建構函式,根據其引數個數的不同或引數型別的不同來區分它們,即建構函式的過載。
2、 類的成員物件
類包含資料成員和成員函式。當類中的成員資料是另乙個類的物件時,我們就說這個類是該類的成員物件。
3、 基類
通過繼承機制,可以利用已有的資料型別來定義新的資料型別。所定義的新的資料型別不僅擁有新定義的成員,而且還同時擁有舊的成員。我們稱已存在的用來派生新類的類為基類,又稱為父類。
4、 建構函式的呼叫順序
我們來看下面一段**:
class b1 ;
class b2 ;
class b3 ;
class c: public b2, public b1, public b3
private:
b1 memberb1;
b2 memberb2;
b3 memberb3; };
void main( )
執行後的結果如下:
constructing b2 2
constructing b1 1
constructing b3 *
constructing b1 3
constructing b2 4
constructing b3 *
為什麼會有以上的結果?
眾所周知建構函式的執行次序如下:
呼叫基類建構函式,呼叫順序按照他們的繼承時宣告的順序。
呼叫內嵌成員物件的建構函式,呼叫順序按照他們在類中宣告的順序。
派生類的建構函式體中的內容。
析構函式的呼叫順序相反。
那麼再來看以上的例子就很容易理解了。b2、b1、b3是c的基類,按照上述的順序,我們先要構造基類,然後才是子物件,最後是其本身的建構函式所以先要執行這三個類的建構函式。在構造時按照他們在類中的順序,首先呼叫b2的建構函式
b2(int j)
中,將b的值傳給了b2的建構函式,b為2,故列印出:
constructing b2 2
接下來要構造的是b1了。顯然在c的預設引數構造列表中將a的值傳給了b1,
所以列印出:
constructing b1 1
b3在構造時沒有傳遞引數,呼叫b3( ){cout<<"constructing b3 *"<
列印出:
cout<<"constructing b3 *
這時基類的建構函式已經執行完畢,接著該處理內嵌成員物件的建構函式了。
我們看到c類有三個物件:b1 memberb1;b2 memberb2;b3 memberb3;,按照建構函式的呼叫順序,我們需要按照他們在類中宣告的順序來分別構造memberb1、memberb2、 memberb3。在預設的引數列表中,用c來構造了memberb1,用d來構造memberb2,
故列印出:
constructing b1 3
constructing b2 4
constructing b3 *
最後呼叫本身的建構函式,由於函式體為空,故什麼也沒有列印出來。
總結下來,我們必須明確的是當乙個類繼承與基類,並且自身還包含有其他類的成員物件的時候,建構函式的呼叫順序為:呼叫基類的建構函式->呼叫成員物件的建構函式->呼叫自身的建構函式。建構函式的呼叫次序完全不受建構函式初始化列表的表示式中的次序影響,與基類的宣告次數和成員物件在函式中的宣告次序有關
構造函式呼叫順序
1 建立派生類的物件,基類的建構函式函式優先被呼叫 也優先於派生類裡的成員類 2 如果類裡面有成員類,成員類的建構函式優先被呼叫,靜態成員優先呼叫 3 基類建構函式如果有多個基類則建構函式的呼叫順序是某類在類派生表中出現的 順序而不是它們在成員初始化表中的順序 4 成員類物件建構函式如果有多個成員類...
建構函式(構造器)的呼叫順序
package demo2 class meal class bread class cheese class lettue class lunch extends meal class portablelunch extends lunch public class demo1 extends p...
C 構造函式呼叫順序
class y class x public y x one 建構函式的呼叫順序是下面的順序 y 基類的建構函式 x 繼承類的建構函式 對於多基類的情況,下面是乙個例子 class x public y,public z x one 建構函式以宣告的次序呼叫。y 基類建構函式首先被呼叫 z x 虛基...