簡體   English   中英

如果我在 C++ 的類構造函數中顯式構造它,是否會在類成員變量上調用默認構造函數?

[英]Is a default constructor called on a class member variable if I am explicitly constructing it in the class constructor in c++?

因此,如果我有以下內容:

class MyClass{
    public:
        MyClass(){
            // do other stuff
            *oc = OtherClass(params);
        }
    private:
        OtherClass* oc;
}

什么時候在 OtherClass 上調用構造函數? 是否會在 MyClass 初始化開始時立即調用其默認值,然后在 MyClass 構造函數期間使用其值構造函數重新定義? 或者它只是在“//做其他事情”期間不存在。 如果沒有為其他類提供默認構造函數,只有一個值怎么辦? 在定義為成員變量的地方構造它是一種好習慣嗎?

默認構造函數是可以不帶參數調用的構造函數。 例如,這是一個默認構造函數:

struct foo { 
    foo(){}    // (should not actually be user defined)
};

這也是一個默認構造函數:

struct bar {
    bar(int x = 42) {}
};

在您的代碼中,調用的構造函數可能是默認構造函數,但這對您的代碼無關緊要,因為您確實傳遞了一個參數。

什么時候在 OtherClass 上調用構造函數?

在行*oc = OtherClass(params); .

是否會在 MyClass 初始化開始時立即調用其默認值,然后在 MyClass 構造函數期間使用其值構造函數重新定義?

如果不提供初始化器成員,則默認初始化。 對於指針來說令人困惑的是,這意味着它沒有被初始化。

或者它只是在“//做其他事情”期間不存在。

該成員之前確實存在,但其值是不確定的。 您不能在不調用未定義行為的情況下使用該值。

如果沒有為其他類提供默認構造函數,只有一個值怎么辦?

看上面。 OtherClass的默認構造函數的存在與此處無關。 如果成員是OtherClass而不是指針,這將是相關的,因為對於類類型的成員,默認初始化調用默認構造函數。

在定義為成員變量的地方構造它是一種好習慣嗎?

為成員提供初始化程序而不是在構造函數中分配是一種很好的做法:

class MyClass{
    public:
        MyClass() : oc(params) {
        }
    private:
    

    OtherClass oc;
}

我用實例而不是指針替換了成員,因為使用原始指針作為成員會打開一罐蠕蟲,需要更長的答案。 有關更多信息,請閱讀什么是三法則? . 請注意,當成員不是指針而是OtherClass時, OtherClass是否具有默認構造函數突然變得很重要,因為如果您不提供初始值設定項,則該成員將被默認構造。 盡管在上面我使用了成員初始化器列表,並且該成員將由帶有一個參數的構造函數初始化。

ÓtherClass *oc; 是一個指針,因此沒有構造函數。 必須先將其初始化為有效對象,然后才能取消引用它。

您可以確保通過初始化oc來初始化它:

MyClass() : oc(new OtherClass()) {
    ...
    *oc = OtherClass(params);
}

這將在它創建的類時創建一個虛擬oc ,然后復制或移動將真實對象分配給*oc 這很浪費,為什么不直接用最終值初始化它:

MyClass() : oc(new OtherClass(params)) {
    ...
}

或者如果您必須先計算參數:

MyClass : oc(nullptr) {
    ...
    oc = new OtherClass(params);
}

不需要首先使用nullptr初始化oc ,但它非常便宜,並且它確保意外使用oc將訪問 nullptr 並失敗,而不是oc是一些可能不會崩潰的隨機值。

您還可以並且更好地通過內聯以下內容來確保初始化:

class MyClass {
    ...
    private:
        OtherClass *oc(nullptr);
}

這樣,只要您不在構造函數的初始化程序列表中初始化oc ,編譯器就會初始化它。


那就是說:你真的需要一個指針嗎? 您需要一個析構函數、復制/移動構造函數和 aissgnment 運算符來直接處理指針。 Otherclass oc; 處理起來會容易得多。

但是如果你確實需要一個指針,那么你應該使用一個智能指針來為你處理所有權。 這意味着使用std::unique_ptr或更可能的std::shared_ptr 那樣的話,你甚至可能不需要構造函數之外的任何東西。 但是想想復制/移動共享指針意味着什么。 閱讀有關0/3/5 的規則

暫無
暫無

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

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