合成的默認構造函數定義為delete的一種情況(針對C++11標准)


1. 默認初始化

如果定義變量時沒有指定初值,則變量會被默認初始化,此時變量被賦予了“默認值”。

對於類類型的變量來說,初始化都是依靠構造函數來完成的。因此,即使定義某個類的變量(對象)時沒有提供初始化式,我們也能通過類的默認構造函數來完成初始化。即,“默認值”由默認構造函數來決定(前提是該類有默認構造函數)。

對於內置類型的變量來說,當定義沒有初始化式的變量時,系統有時會幫我們初始化變量。“默認值”由定義的位置決定:定義於任何函數體之外的變量被初始化為0;定義在函數體內部的變量默認值是未定義的,不會由系統自動初始化,雖然值是未定義的,但是仍然是有一個默認值的。即,“默認值”由定義的位置決定。

2. 針對const類型的默認值

const對象一旦創建后,其值就不能再改變,所以const對象必初始化(注意,必須由用戶來決定怎么初始化從而給定默認值,而不是依靠系統)。

對於內置類型變量來說,我們自己初始化時,只有一種辦法,就是提供值。即const內置類型變量無法默認初始化,系統也不會提供默認值。因此類似以下的代碼語法上就是錯的:

const int ival;   // 錯誤,ival沒有初始化

對於類類型變量來說,我們通過構造函數來完成變量的初始化,這當然也包括了默認構造函數(必須是用戶自定義的默認構造函數,而非系統合成的默認構造函數),因此可以在定義對象時,不提供初始化式:

const A object;   // 正確,通過默認構造函數來初始化

3. 合成的默認構造函數定義為delete的一種情況

1. 編譯器創建的合成的默認構造函數按以下規則初始化類的數據成員:

-> 如果該數據成員有類內初始值,則在默認構函數中用類內初始值來初始化成員。

-> 如果該數據成員沒有類內初始值,則在默認構造函數中該成員采取默認初始化。(更確切的說,是使用該成員的默認值)

2. 聯系《primer 5th》page450-451

-> 如果在類中,有一個沒有類內初始化器的const內置類型成員,則該成員沒有辦法初始化(因為const內置類型變量必須由用戶自己來初始化,注意:const的內置類型變量是無法默認初始化的)。因為該成員沒有辦法自己初始化(通過以上1的兩種方式初始化),因此該類的默認構造函數定義為刪除(delete)。

-> 如果在類中,有一個沒有類內初始化器的const類類型成員,且其類型沒有顯示定義默認構造函數(導致該const類類型成員也沒有辦法默認初始化),因此該類的默認構造函數定義為刪除(delete)。

-> 如果在類中,有一個沒有類內初始化器的類類型成員,且其類型沒有定義默認構造函數(導致類類型成員也沒有辦法默認初始化),因此該類的默認構造函數被定義為刪除(delete)。

有關此處的delete情況小結:

1. 首先需要明確內置類型變量是否可以默認初始化取決於變量位置,但無論如何,對於非const內置類型變量而言,一定會有一個默認值,即便其也許是未定義的;而對於類類型變量,如果要有默認值,必須要有默認構造函數,如果沒有默認構造函數,其無法進行默認初始化。

2. 對於沒有類內初始化器的內置類型成員來說,const使成員失去了擁有默認值的能力。

3. 對於沒有類內初始化器的類類型成員來說,加const,必須有用戶自定義的默認構造函數,才可以默認初始化,從而擁有默認值。不加const,那么只要有默認構造函數(隱式、顯示均可)即可默認初始化,從而擁有默認值。

4. 本質含義

如果一個類有數據成員不能默認構造(更確切的說是無法擁有默認值)、拷貝、復制或銷毀,則對應的成員函數將被定義為delete。

5. 與c++03標准區別

系統合成的構造函數定義為delete是c++11標准中提出的概念。

對於c++03標准而言,在有默認構造函數,且不是用戶自定義的默認構造函數的情況下,那么我們默認隱式的默認構造函數一定是存在的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM