先說c++新手一般的誤解:
1.任何乙個類如果沒有定義預設建構函式,編譯器會自動合成乙個預設建構函式。
2.編譯器合成出來的預設建構函式,會顯式的設定類中成員變數的值。
先看乙個最基本的例子:
從圖中可以看到物件a並沒有被初始化,即編譯器沒有為類a合成乙個預設建構函式。其實c++標準委員會曾敘述,如果沒有任何使用者宣告的建構函式,那麼會有乙個預設構造被隱式構造出來,但是這個隱式宣告出來的預設建構函式將是乙個trivial(淺薄無能的,沒啥用的)建構函式。
下面說在哪幾種情況下編譯器會自動合成預設建構函式(共四種情況):
情形一:
當成員變數中有乙個或多個類的物件,且該物件帶有預設建構函式,這時編譯器需要為該類合成乙個預設建構函式,不過這個合成操作只有在建構函式真正被呼叫時才會發生,(即構造物件時)。
從圖中可以發現,此時沒有報錯,且a.x被輸出了乙個隨機值,可以說明編譯器的確為a類合成了預設建構函式,但並沒有給成員變數賦予乙個初值。合成操作只是為了滿足編譯器的需要,而不是程式的需要,所以為了程式可以正確的 執行,還需要程式設計師手動初始化裡面的成員變數。假設a::a() 此時程式設計師手動定義了乙個預設建構函式,那編譯器就不會再合成第二個了。此時你可能會問:編譯器會採取什麼行動呢?
實際上,如果類a包含乙個或乙個以上成員類物件(member class object),那麼類a的每乙個建構函式都必須呼叫每乙個成員類物件的預設建構函式。即編譯器會自動擴張建構函式,擴張後的c++偽碼為:
a::a()
如果有多個類成員物件,則按照宣告順序來依次呼叫它們各自的預設建構函式。
情形二:帶有預設建構函式的基類
與情形一類似,如果基類帶有預設建構函式,那這個派生類也需要合成乙個預設建構函式,且派生類的預設建構函式中需要先呼叫基類的建構函式。如果設計者自定義了多個建構函式,但是沒有預設建構函式,則編譯器會擴張現有的每乙個建構函式,將所有成員類物件的預設建構函式安插進去,同情形一。
情形三:帶有虛函式的類
分為兩小類情形:1)class 宣告或繼承了乙個虛函式
2) class派生自乙個繼承串鏈,其中有乙個或多個虛函式
帶有虛函式時會有兩個擴張行為:1)虛函式表(vtbl)會被編譯器產生出來,內放class裡的虛函式位址。2)每乙個class object中都會有乙個額外的指向虛函式表的指標(vptr)被編譯器合成出來。
情形四:帶有虛基類的類
對於虛繼承的類中都會安插乙個_vbcx指向虛基類x
C 預設建構函式
c 預設建構函式 一直認為若程式設計師沒有自己定義無引數的建構函式,那麼編譯器會自動生成預設建構函式,來進行對成員函式的初始化,但這種認為是有誤的,不全面的.預設的建構函式分為有用的和無用的,所謂無用的預設建構函式就是乙個空函式 什麼操作也不做,而有用的預設建構函式是可以初始化成員的函式。對建構函式...
c 預設建構函式
c 什麼時候合成預設建構函式?c 合成的預設建構函式都做些什麼?以下三個條件同時滿足 源程式中沒有宣告任何建構函式 編譯器需要該類有預設建構函式 程式中需要呼叫預設建構函式 預設建構函式是以編譯單元為單位生成的 什麼時候編譯器需要預設建構函式 該類中有 有預設建構函式 的成員物件 該類繼承乙個有預設...
C 預設建構函式
c 預設建構函式是對類中的引數提供預設值的建構函式,一般情況下,是乙個沒有引數值的空函式,也可以提供一些的預設值的建構函式,如果使用者沒有定義建構函式,那麼編譯器會給類提供乙個預設的建構函式,但是只要使用者自定義了任意乙個建構函式,那麼編譯器就不會提供預設的建構函式,這種情況下,容易編譯報錯,所以正...