传递构造函数的首选参数

Preferred parameter passing for constructors

本文关键字:参数 构造函数      更新时间:2023-10-16

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

一个简化的例子。

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&,然后将参数复制到成员中。
  • &&,然后用该参数初始化成员

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

我的直觉告诉我使用右值引用,但我不确定我理解所有的优点和缺点。

选项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&&&之间重载一个或两个以上的参数,这个公式将变得不现实。