簡體   English   中英

構造函數初始化

[英]Constructor initialization

我正在閱讀Andrew Koenig和Barbara E. Moo撰寫的“ Accelerated C ++”,並且我正在討論有關構造函數(5.1)的章節。

他們在這里提到

我們說過,構造函數的存在是為了確保在其數據成員處於合理狀態下創建對象。 通常,此設計目標意味着每個構造函數都應初始化每個數據成員。 對於內置類型的成員,賦予成員一個值特別重要。 ...

盡管我們僅對midtermfinal了顯式初始化,但其他數據成員也進行了隱式初始化。 具體來說, nstring默認構造函數初始化, homeworkvector默認構造函數初始化。

他們正在談論的課程是

class Student_info {
public:
    std::string name() const (return n;}
    bool valid() const {return !homework.empty();}
    std::istream& read(std::istream&);

    double grade() const;
private:
    std::string n;
    double midterm, final;
    std::vector<double> homework;
};

他們的默認構造函數是

Student_info::Student_info(): midterm(0), final(0) {}

我只想澄清一下,這意味着像intdouble這樣在沒有std:: ,需要專門初始化該術語之前?

那是對的。
但是std ::不是您想要的。

除非您顯式進行初始化,否則任何基本類型都不會初始化。

因此, char/int/float/pointers等。此外(如下面的Ian所述),沒有顯式構造函數的任何類/聯合將默認初始化其成員(這意味着基本的(並且對於不具有顯式構造函數的類/聯合的成員s)他們未定義)。

旁注:

  • 此規則適用於自動和動態存儲期限對象
  • 靜態和線程存儲持續時間對象初始化為零。

intdouble是內置類型,而不是類,因此它們沒有默認的構造函數,並且默認情況下未定義。 例如:

int a;
Student_info s;

兩個變量的語法是相同的,但值a未定義,而值s被定義,因為Student_info s實際調用的構造,即, Student_info s = Student_info();

作者只是試圖顯示一個默認構造函數,其中所有默認值都等於0。對於字符串和向量,這些將為空。 對於int和double之類的基本類型,在聲明過程中這些基本類型的初始值默認為變量所指向的內存中的值。 這確實取決於編譯器

它與std名稱空間無關。 n和家庭作業是類,在構造Student_info時將調用它們的構造函數。 但是midterm和final是原始值,沒有針對它們的構造函數。 在構造函數中初始化基本成員不是必需的,而是一種好方法。

還有更多。

1)對於原始或內置類型, 隱式初始化(或編譯器初始化)表示無操作(不執行任何操作)。

2)對於原始或內置類型, 顯式初始化(或由程序員初始化)很明顯:)

如您的示例:

    Student_info::Student_info(): midterm(0), final(0) {}

3)對於非原始類型, 隱式初始化(或編譯器初始化)意味着編譯器可以(也可以不)為初始化目的而合成構造函數。

  Usually, a constructor is synthesized by the compiler under the following cases: a) The non-primitive type is polymorphic or derives from some polymorphic/non-polymorphic types, b) The non-primitive type has a polymorphic/non-polymorphic member. Compiler synthesized constructor will usually have code to a) initialize v-pointer to v-table, b) call base class constructor, c) call constructors of members, so on, basically driven by the definition of non-primitive type. 

4)對於非原始類型, 顯式初始化(或由用戶提供的構造函數初始化)意味着編譯器將調用用戶定義的構造函數,而不是出於初始化目的而合成一個。

例如,將調用由各個非基本類型(例如std :: string或std :: vector)定義的默認構造函數。

**

注意:編譯器可能仍會根據需要在用戶定義的構造函數內擴展代碼,以進行一些幕后初始化(有關此類需求,請參見上面的第3步)。 這樣的擴充代碼將始終插入到構造函數中用戶定義的代碼之前!

**

暫無
暫無

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

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