2015-07-20 83 views
0

使用C++ 11標準,我可以以兩種方式初始化類成員:初始化類成員的最佳方法是什麼?

class MyClass 
{ 
private: 
    int a = 5; 
}; 

class MyClass 
{ 
private: 
    int a; 
public: 
    MyClass() 
    { 
     a = 5; 
    } 
}; 

是任一方法優於其他任何原因,或者是更大的個人風格的選擇?

+1

你錯過了一個使用ctor初始值設定項的例子。第二個例子是將一個值賦給'a',因爲它已經被初始化了。整數類型不太重要,對於複雜類型更重要。 –

+1

@KaiSchmidt:CaptionObvious指的是這個:'MyClass():a(5){}',他的意思是「*在**已經被初始化之後*'爲'a' **賦值。 –

+0

我明白了。我是否應該使用此方法初始化多個成員,語法如何? –

回答

3

第二個示例是而不是初始化。

所以,在這兩個例子中,第一個是初始化類成員的最好方法。

的傳統方法來初始化看起來像這樣:

class MyClass 
{ 
private: 
    int a; 
public: 
    MyClass() 
     : a(5) 
    {} 
}; 

雖然我們現在有內嵌initialisers作爲你的第一個例子中,由於C++ 11。

+0

按照我的第二個問題,使用ctor初始值設定項還是內聯項目更好? –

+0

@KaiSchmidt:根據哪個度量標準「更好」?爲了誰?在什麼情況下?你沒有說明任何條件,目標或標準。因此,你的問題是不可能回答的。停止尋找硬性規則和快速規則。 –

+0

只要使用更簡單的方法,它們就會解析爲相同的字節碼。 ctor初始化列表可以用在很老的編譯器上,但這是它唯一的好處,如果你更喜歡內聯,它會立即被超過 –

1

This page from the Standard C++ Foundation表明,在其他條件相同的情況下,您應該更喜歡使用初始值設定項列表。那就是:

身高

class Foo { 
    public: 
    Foo(int bar) : m_bar(bar) { } 
    private: 
    int m_bar; 
}; 

class Foo { 
    public: 
    Foo(int bar) { 
     m_bar = bar; 
    } 
    private: 
    int m_bar; 
}; 

他們的理由:

考慮下面的構造函數,使用初始化列表初始化成員對象x_Fred::Fred() : x_(whatever) { }。這樣做的最常見好處是提高了性能。對於 示例,如果表達式與成員 變量x_的類型相同,則直接在x_內部構造任何表達式的結果 - 編譯器不會單獨複製 對象。即使類型不同,編譯器通常可以在初始化列表上比在 分配中做得更好。

構建構造函數的另一種(低效率)方式是通過賦值 ,如:Fred::Fred() { x_ = whatever; }。在這種情況下,表達式 無論如何都會導致創建一個單獨的臨時對象,並將此臨時對象傳遞給x_對象的賦值運算符。 然後那個臨時對象被銷燬在;。這是低效的。

如果這還不夠糟糕,有效率 的另一個來源在構造函數中使用賦值時:成員對象會得到 其默認構造函數完全構造,這可能爲 例如,分配一些默認內存量或打開一些默認的 文件。如果任何表達式 和/或賦值運算符使對象關閉該文件和/或釋放該內存(例如,,如果默認的構造函數沒有分配足夠大的內存池或打開錯誤的文件)。

結論:如果您使用初始化列表而不是賦值,您的代碼將運行得更快。

關於默認初始化(如Foo(): m_bar(5) { })我也會去的初始化列表的方法(或C++ 11成員初始化方法),只是爲了與上述方針的一致性。