2011-10-04 61 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参数将只接受右值。 –

相关问题