亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

C ++中是否有隱式默認構造函數?

C ++中是否有隱式默認構造函數?

C++
喵喔喔 2019-11-11 14:21:57
在我目前正在閱讀的書中(C ++ Without Fear),它說,如果您沒有為類聲明默認的構造函數,則編譯器會為您提供一個,該構造函數“將每個數據成員清零”。我已經對此進行了試驗,但沒有看到任何歸零行為。我在Google上也找不到任何提及此內容的信息。這僅僅是特定編譯器的錯誤還是怪癖?
查看完整描述

3 回答

?
繁華開滿天機

TA貢獻1816條經驗 獲得超4個贊

如果未定義構造函數,則編譯器將為您定義默認構造函數。

執行此

默認構造函數是:

  • 默認構造基類(如果基類沒有默認構造函數,則編譯失敗)

  • 默認按照聲明的順序構造每個成員變量。(如果成員沒有默認構造函數,則這是編譯失?。?。

注意:
POD數據(int,float,pointer等)沒有顯式構造函數,但是默認操作是不做任何事情(在C ++哲學的風向標中;除非明確要求,否則我們不愿為之付費)它)。

如果未定義析構函數/復制構造函數/賦值運算符,則編譯器將為您構建其中的一個(因此,類始終具有析構函數/復制構造函數/賦值運算符(除非您作弊并明確聲明一個但不定義它))。
默認實現為:

析構函數:

  • 如果定義了用戶定義的析構函數,請執行提供的代碼。

  • 以聲明的相反順序調用每個成員的析構函數

  • 調用基類的析構函數。

復制構造函數:

  • 調用基類Copy構造函數。

  • 按聲明順序為每個成員變量調用復制構造函數。

分配運算符:

  • 調用基類的賦值運算符

  • 按聲明的順序調用每個成員變量的賦值運算符。

  • 返回對此的引用。

注意POD數據的復制構造/分配運算符只是復制數據(因此,與RAW指針相關的淺表復制問題)。


查看完整回答
反對 回復 2019-11-11
?
滄海一幻覺

TA貢獻1824條經驗 獲得超5個贊

編譯器會自動生成默認構造函數嗎?

隱式生成的默認構造函數是否執行零初始化?

如果您從法律上解析2003年標準的語言,則答案是肯定的,否。但是,這還不是全部,因為與用戶定義的默認構造函數不同,從頭創建對象時并不總是使用隱式定義的默認構造函數 -還有其他兩種情況:無構造和成員明智的值初始化。


“無構造”的情況實際上只是一種技術問題,因為它在功能上與調用瑣碎的默認構造函數沒有什么不同。另一種情況是更加有趣:成員明智值初始化通過使用調用“()” [仿佛明確調用一個沒有參數的構造函數]和它繞過什么技術上稱為的默認構造函數。相反,它對每個數據成員遞歸執行值初始化,對于原始數據類型,最終將解析為零初始化。


因此,實際上,編譯器提供了兩個不同的隱式定義的默認構造函數。其中一個確實對原始成員數據執行零初始化,而另一個則不執行。以下是一些示例,說明了如何調用每種類型的構造函數:


    MyClass a; // default-construction or no construction

    MyClass b = MyClass(); // member-wise value-initialization


    new MyClass; // default-construction or no construction

    new MyClass(); // member-wise value-initialization

注意:如果確實存在用戶聲明的默認構造函數,則按成員值初始化將簡單地調用它并停止。


這是標準對此的詳細說明...


如果不聲明構造函數,則編譯器會隱式創建一個默認構造函數[12.1-5]


默認構造函數不初始化基本類型[12.1-7]


MyClass() {} // implicitly defined constructor

如果使用“()”初始化對象,則不會直接調用默認構造函數。相反,它會引發很長的規則序列,稱為值初始化 [8.5-7]


值初始化的最終效果是,永遠不會調用隱式聲明的默認構造函數。相反,將調用遞歸的按成員值初始化,最終將對所有原始成員進行零初始化,并在具有用戶聲明的構造函數的任何成員上調用默認構造函數[8.5-5]


值初始化甚至適用于原始類型-它們將被零初始化。[8.5-5]


a = int(); // equivalent to int a=0;

對于大多數目的來說,所有這些實際上都是沒有實際意義的。類的編寫者通常不能假定數據成員在隱式初始化序列中將被清零-因此,如果任何自管理類具有需要初始化的原始數據成員,則它應該定義自己的構造函數。


那么什么時候重要呢?


在某些情況下,通用代碼可能要強制初始化未知類型。值初始化提供了一種方法。請記住,如果用戶提供了構造函數,則不會發生隱式零初始化。


默認情況下,std :: vector包含的數據是值初始化的。這可以防止內存調試器識別與其他情況下未初始化的內存緩沖區相關的邏輯錯誤。


vector::resize( size_type sz, T c=T() ); // default c is "value-initialized"

可以使用值初始化語法對原始類型或“普通數據”(POD)類型結構的整個數組進行零初始化。


new int[100]();

這篇文章提供了有關標準版本之間變化的更多詳細信息,并且還指出了在主要編譯器中以不同方式應用標準的情況。


查看完整回答
反對 回復 2019-11-11
?
月關寶盒

TA貢獻1772條經驗 獲得超5個贊

C ++會生成一個默認的構造函數,但前提是您不提供自己的構造函數。該標準并沒有說明將數據成員清零。默認情況下,當您第一次構造任何對象時,它們是未定義的。


這可能會造成混淆,因為大多數C ++基本類型確實具有默認的“構造函數”,這些默認構造函數會將它們初始化為零(int(),bool(),double(),long()等),但是編譯器不會調用他們像對象對象一樣初始化POD成員。


值得注意的是,STL 確實使用這些構造函數來默認構造保存原始類型的容器的內容。


查看完整回答
反對 回復 2019-11-11
  • 3 回答
  • 0 關注
  • 559 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號