2011-10-04 64 views
2

是否有傳遞構造函數參數的首選方法?特別是如果這些構造函數參數用於初始化成員變量。構造函數傳遞的首選參數

一個簡化的例子。

class Example 
{ 
public: 
    Example(/*type-1*/ str, /*type-2*/ v): 
     m_str(str), 
     m_v(v) 
    { } 

    /* other methods */ 

private: 
    std::string m_str; 
    std::complex<float> m_v; 
}; 

選項爲:

  • 通過噪聲值,然後std::move對象進入構件。
  • const&,然後將參數複製到成員中。
  • &&,然後用該參數初始化該成員。

什麼應該是我的默認/首選參數傳遞樣式?
它是否因不同的參數類型而改變?

我的直覺說使用右值引用,但我不知道我明白所有的優點和缺點。

+0

「&&,然後使用參數」'示例(std :: string && str):m_str(str){}'初始化成員將複製一次。只是爲了說清楚。 –

+0

@ R.MartinhoFernandes:編譯器不會使用'std :: string'的移動構造函數嗎?爲什麼它會喜歡複製而不是移動? 'std :: forward'會解決這個問題嗎? –

+1

因爲指定的右值引用是左值。 '示例(std :: string && str):m_str(std :: move(str)){}'移動。 –

回答

6

選項1:

class Example 
{ 
public: 
    Example(std::string str, const std::complex<float>& v): 
     m_str(std::move(str)), 
     m_v(v) 
    { } 

    /* other methods */ 

private: 
    std::string m_str; 
    std::complex<float> m_v; 
}; 

這有相當不錯的表現,很容易代碼。當它將一個左值綁定到str時,它落後於最佳值的一個地方。在這種情況下,您可以執行復制構建和移動構建。最佳只是一個複製結構。請注意,std::string的移動結構應該非常快。所以我會從這開始。

但是如果你真的需要拉最後循環出本作的表現,你可以這樣做:

選項2:

class Example 
{ 
public: 
    Example(const std::string& str, const std::complex<float>& v): 
     m_str(str), 
     m_v(v) 
    { } 
    Example(std::string&& str, const std::complex<float>& v): 
     m_str(std::move(str)), 
     m_v(v) 
    { } 

    /* other methods */ 

private: 
    std::string m_str; 
    std::complex<float> m_v; 
}; 

這種方法的主要缺點是有過載/複製構造函數邏輯。事實上,如果您需要在const&&&之間超載的超過一個或兩個參數,則此公式將變得不切實際。

+0

我只使用非平凡構造函數傳遞大多數對象時使用了選項2。我使用選項1,如果我有不止一個對象與一個不平凡的構造函數。 –

+0

如果用戶將'const&'字符串傳遞給'&&'構造函數會發生什麼?我認爲它會創建一個副本。該副本可以被移入'std :: string'成員。 –

+1

@deft_code:不會編譯。一個右值ref參數將只接受右值。 –

相關問題