C 建構函式詳解

2021-08-09 09:13:48 字數 2611 閱讀 3036

以前一直對c++類的建構函式工作一知半解,最近重新溫習《c++ primer》,才詳細理解了類的建構函式的工作,特意寫個部落格記錄一下。

沒有顯式定義建構函式的情況

相信稍微了解過c++的同學,都知道c++類有乙個特殊的成員函式,也是必須的成員函式,那就是建構函式。

所以嚴格意義上來講,建構函式體並不屬於物件的初始化。但是,普遍程度上,我們認為這兩部分都屬於物件的初始化。

還記得我剛才說到建構函式是必須的麼?你們可能會反駁,為什麼如以下的類,卻能成功編譯。

class rect

};

的確如以上的類可以被正確編譯,並且它的確沒有顯式定義建構函式。但是,請注意我在這裡用了顯式,結合我剛才說建構函式是必須的,那麼只有一種情況:這裡隱式地產生了建構函式。

那麼這個建構函式是誰產生的呢?既然我們沒有主動去構造,那麼只有編譯器了。實際上,就是編譯器產生的這個建構函式。並且由編譯器產生的建構函式有乙個很規範的名字:合成的預設建構函式

那麼這個預設建構函式到底是如何工作的呢?它將會按照以下規則初始化類的資料成員。

別急,讓我們來慢慢分析下這個規則:

class rect

};

如果這個rect類現在變成了這個樣子,那麼當執行rect c時,c的資料成員是怎麼樣的呢?

顯式定義了建構函式的情況

我們再把上面的**改動一下

class rect

rect(int _width, int _height)

};

可以看到在這裡我們定義了乙個帶參的建構函式。很容易理解,當執行rect c(10,9);時,c.width=10,c.height=9。但是當執行rect c時,會怎麼樣呢?沒錯,編譯器會報錯!你可能會說,不是有合成的預設建構函式麼?對,編譯器的確會建立合成的預設建構函式,但是那有乙個前提,就是我們沒有定義任何形式的建構函式。在以上**中,定義了乙個建構函式,所以編譯器不會再幫我們建立合成的預設建構函式了。所以,我們最好再給類新增乙個預設建構函式,如下:

class rect

rect() = default;

rect(int _width, int _height)

};

這裡的rect() = default;表示要求編譯器生成預設建構函式,當然你也可以自己寫乙個預設建構函式。

那麼我們再來變一下**。

class rect

rect() = default;

rect(int _width): width( _width) {}

};

rect(int _width): width( _width) {}這句**採用了初始列表的寫法,其實就是相當於width = _width;並且初始列表的執行在函式體之前,另外初始列表也有其他一些規則,但是在這裡我們不詳談。我們要關注的是當執行rect c(10);時c.height的值,c.width的值是明確的,就是10,那麼c.height呢?因為rect的建構函式只有對c.width的初始化,所以就以與合成的預設建構函式相同的方式隱式初始化,也就是先檢查有沒有類內初始值,沒有的話就預設初始化。因為c.height有類內初始值0,所以c.height被初始化為0。

繼承關係中建構函式的執行順序

其實在子類繼承父類這種情況下,建構函式的執行順序其實是很簡單的,只要牢記大方向是先祖先後自己。並且這個自己分為兩個部分:先初始化列表部分,再是建構函式體部分

子類繼承多個父類

在子類的繼承列表中,按照繼承順序,對於每乙個繼承的父類,使用如上規則選擇呼叫合適的構造方法,然後再進行子類自身的初始化工作。

我們已經了解了繼承中的建構函式執**況。那麼讓我們做乙個小小的測試。

class a

a(int b)

int a;

};class c :public a

};class b:public a

c c;

};int main()

請問最後的顯示結果是什麼?答案是:

construct a

coustruct a with

param

construct c

construct b

為什麼呢?我們一起來分析一下這個過程:

因為b是a的子類,並且b的建構函式並未顯式呼叫父類a的建構函式,所以呼叫a的預設建構函式,所以列印construct a。

此時開始執行b自身的建構函式,先進行初始化部分,由於b的初始化部分沒有顯式初始化其資料成員c,所以預設初始化c,即呼叫c的預設建構函式。

由於c也是a的子類,並且c的建構函式顯式呼叫了a的有參建構函式,所以列印construct a with param,然後執行c自身的建構函式,即列印construct c。

最後執行b自身的建構函式體部分,即列印construct b。

C 建構函式詳解

c 類的建構函式詳解 一 建構函式是幹什麼的 class counter private 資料成員 int m value 該類物件被建立時,編譯系統物件分配記憶體空間,並自動呼叫該建構函式 由建構函式完成成員的初始化工作 eg counter c1 編譯系統為物件c1的每個資料成員 m value...

c 建構函式詳解

c 類的建構函式詳解 一 建構函式是幹什麼的 class counter private 資料成員 int m value 該類物件被建立時,編譯系統物件分配記憶體空間,並自動呼叫該建構函式 由建構函式完成成員的初始化工作 eg counter c1 編譯系統為物件c1的每個資料成員 m value...

C 建構函式詳解

c 建構函式的知識在各種c 教材上已有介紹,不過初學者往往不太注意觀察和總結其中各種建構函式的特點和用法,故在此我根據自己的c 程式設計經驗總結了一下c 中各種建構函式的特點,並附上例子,希望對初學者有所幫助。c 類的建構函式詳解 一 建構函式是幹什麼的 class counter private ...