构造函数的首选参数传递

def*_*ode 2 c++ constructor rvalue-reference c++11

是否有传递构造函数参数的首选实践?特别是如果这些构造函数参数用于初始化成员变量.

一个简化的例子.

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;
};
Run Code Online (Sandbox Code Playgroud)

选项是:

  • 按值传递,然后std::move将对象传入成员.
  • const&,然后将参数复制到成员中.
  • &&,然后使用参数初始化成员.

什么应该是我的默认/首选参数传递样式?
它是否随着不同的参数类型而改变?

我的直觉说使用rvalue-references,但我不确定我理解所有的优点和缺点.

How*_*ant 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;
};
Run Code Online (Sandbox Code Playgroud)

这具有相当好的性能并且易于编码.当你将一个左值绑定到的时候,它与最佳值相差一个地方str.在这种情况下,您执行复制构造和移动构造.最佳只是复制结构.请注意,a的移动构造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;
};
Run Code Online (Sandbox Code Playgroud)

此选项的主要缺点是必须重载/复制构造函数逻辑.实际上,如果您需要在const&和之间重载多于一个或两个参数,则此公式将变得不切实际&&.