簡體   English   中英

為什么編譯器發出的 C++ 默認構造函數“不好”?

[英]Why is the Compiler-Emitted C++ Default Constructor “bad”?

有人可以解釋以下是什么意思嗎?

如果您的 class 定義了成員變量並且沒有其他構造函數,則必須定義默認構造函數。 否則編譯器會為你做這件事,很糟糕。

他們所說的“糟糕”是什么?

從該鏈接的擴展:

“這樣做的原因是,如果你沒有其他構造函數並且沒有定義默認構造函數,編譯器會為你生成一個。這個編譯器生成的構造函數可能不會明智地初始化你的 object。”

可能指沒有提供 ctor 時new Tnew T()的不同之處。

最好確保 object 是在已知的 state 中創建的。 默認情況下,原始變量不會設置為零,因此您最終可能會遇到並不總是出現的細微錯誤。 通過將成員變量初始化為合理變量,一切都變得更加可預測。

默認構造函數的唯一問題是它只初始化編譯器認為必須初始化的東西,而不是你可能認為需要初始化的東西。 基本上,這意味着它將為具有默認初始化程序的對象調用初始化程序。 它不會將指針或簡單類型(如int )設置為健全的值等。如果這足夠了,那么默認構造函數就不是“壞的”。 當它不夠時,這是一個錯誤(在您的代碼中),您沒有使用正確的初始化定義必要的默認構造函數。

帶着一粒鹽——或者可能是一卡車的鹽——拿谷歌風格指南。

確實,編譯器生成的默認構造函數不一定會以有意義的方式初始化內置類型的成員。 如果你想這樣做,那么是的,它不這樣做是不好的。 OTOH,如果您不希望這樣做,那么這樣做也可能有些糟糕(浪費)。

底線:有時會編寫自己的默認 ctor,但它們傾向於例外,而不是規則。 盡管在 C++ 中有很多簡單的經驗法則可以涵蓋很多情況,並且可以防止很多問題,但這真的不是其中之一——在這里你非常需要知道編譯器生成的 ctor 會做什么,如果你要自己寫,你想要什么不同。

在 Debug 構建中,大多數編譯器用一些魔法值填充未初始化的空間,因此調試是可靠的。 並且提供自定義構造函數可以防止某些 POD 優化。

事實上,它只是為了確保人們明確說明任何 object 的無效或默認 state 的聲明。

這樣,與實際執行相比,閱讀代碼時就不足為奇了。

但是,認為這是一個公司准則,用於確保每個人都遵循相同的規則,這不是你必須遵循它,因為谷歌這樣做。

事實上,如果您設法使您的所有成員對象在默認構造時都處於有效的 state 中,或者強制您設置構造函數,那么這樣的指導方針就沒有充分的理由。

如果您有任何原始類型作為成員變量(例如 int、float),則默認 ctor 不會初始化它們。 class 類型的成員變量將調用其默認 ctor。

首選成員初始化器列表,因此您的用戶提供的 ctor 可能為空:

class Foo {
 int bar;
 float baz;

 Foo(): bar(0), baz(0.0f) { /* empty ctor body */ }

};

它不會將整數設置為 0 或指向 null 的指針。 它將在具有構造函數的類型的 object 上運行默認構造函數。

有些人會稱之為“不明智”。

這似乎是規則 3 的一個過於簡化的版本,您應該自己定義或保留編譯器版本

  • 復制構造函數
  • 賦值運算符
  • 析構函數

(請注意,通過定義自己的復制構造函數,編譯器不會定義默認構造函數)。

編譯器構建的默認構造函數“什么都不做”,它甚至不會將 object 占用的 memory 歸零

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM