深入探索預設建構函式

2021-10-04 06:12:56 字數 1411 閱讀 7866

問題:傳統認識為:如果我們自己在類中沒有定義任何建構函式,那麼編譯器就會為我們隱式自動生成乙個預設的建構函式,我們稱這種建構函式為「合成的預設建構函式」。事實的真相果真如此嗎?

結論:「合成預設建構函式」,只有在必要的時候,編譯器才會為我們自動合成出來,而不是必然為我們合成出來。那到底什麼時候是必要的呢?

**演示:

#include using namespace std;

class matx

};class mbtx

};int main()

結論(1): 該類mbtx沒有任何建構函式,但是包含乙個型別的成員m_a,而該物件m_a所屬的類matx有乙個預設的建構函式,這個時候編譯器就會該類mbtx合成乙個預設的建構函式,合成的目的是為了呼叫matx裡的預設建構函式。換句話說:編譯器合成了預設的mbtx的建構函式,並且在其中安插**,呼叫matx的預設建構函式。

**演示:

#include using namespace std;

class matx

};class mbtxparent

};class mbtx:public mbtxparent

};int main()

結論(2): 父類帶預設建構函式,子類沒有任何建構函式。原因:子類必須合成乙個預設的建構函式,來呼叫父類這個預設的建構函式。合成的目的就是為了呼叫這個父類的建構函式。換句話說:編譯器合成了預設的建構函式,並在其中安插**,呼叫父類的預設建構函式。

結論(3):如果乙個類中含有虛函式,但是這個類沒有任何的建構函式的時候,編譯器就會為該類生成乙個預設的建構函式。為什麼呢?因為有虛函式的存在。第一點:編譯器會給我們生成乙個基於該類的虛函式表vftable。第二點:在這個預設建構函式中,把類的虛函式表位址賦值給物件的虛函式表指標。(因為物件的首部的虛函式指標必須正確的指向類的虛函式表,這樣才能夠發生多型。)需要說一點,當我們自定義了乙個預設建構函式的時候,編譯器會根據需要擴充預設建構函式。

結論(4):如果乙個類帶有虛基類,編譯器也會為它合成乙個預設建構函式。

虛基類:通過兩個直接基類繼承通乙個間接基類。所以一般是三成,有爺爺grand,有兩個爹a,a2,有孫子c。

**演示:

#include using namespace std;

class grand

;class a :virtual public grand //編譯器會為a生成乙個虛基類表 vbtable

;class a2 :virtual public grand //編譯器會為b生成乙個虛基類表 vbtable

;class c :public a, public a2 //編譯器會為c生成乙個預設建構函式

;int main()

深入探索建構函式

大致分為以下幾類 1 全預設引數初始化,不用傳參。2 半預設引數初始化,只需傳部分引數。3 無缺省引數初始化,定義多少個成員變數,傳多少個引數。4 使用初始化列表初始化,此類初始化更加高效,建議初始化的順序與宣告的順序相同。首先定義乙個日期類如下 class date 半預設引數 無缺省引數 初始化...

深入C 的預設建構函式1

總所周知,建構函式是物件重要的組成部分,承擔了物件的初始化工作。本文主要講c 下物件的預設建構函式的反彙編 或許,這沒什麼用處,但是,知其然,還要知其所以然吧,了解底層,將對我們更好地掌握知識有很大幫助。打牢基礎,將更有利於我們的成長。勿在浮沙築高台 侯捷。當乙個物件沒有宣告建構函式的時候,編譯器會...

初始化列表(深入探索建構函式)

一 類的成員變數有兩種初始化方式 一是建構函式體內進行賦值 二是初始化列表進行初始化。初始化列表以乙個冒號開始,以逗號分隔資料列表,每乙個元素要初始化的值都在括號中。class date private int year int month int day 二 初始化列表更高效 嘗試執行以下 在上面...