C++ 构造函数的首选参数传递

C++ 构造函数的首选参数传递,c++,constructor,c++11,rvalue-reference,C++,Constructor,C++11,Rvalue Reference,是否有传递构造函数参数的首选实践?特别是当这些构造函数参数用于初始化成员变量时 一个简化的例子 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; };

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

一个简化的例子

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;
};
类示例
{
公众:
示例(/*类型1*/str,/*类型2*/v):
m_街(str),
m_v(v)
{ }
/*其他方法*/
私人:
std::字符串m_str;
std::复杂m_v;
};
这些选择包括:

  • 传递值,然后将对象移动到成员中
  • 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;
};
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;
};

此选项的主要缺点是必须重载/复制构造函数逻辑。实际上,如果需要在
常量&
&

“&&&&”之间重载一个或两个以上的参数,然后使用参数“
示例(std::string&&str)”初始化成员,则此公式将变得不切实际:m_str(str){}
将创建副本而不是移动。只是想澄清一下。@R.MartinhoFernandes:编译器不会使用
std::string
的move构造函数吗?为什么它更喜欢复制而不是移动?
std::forward
会解决这个问题吗?因为命名的右值引用是左值<代码>示例(std::string&&str):m_str(std::move(str)){}moves.@deft_code@RMartinhoFernandes这是一件安全的事情。如果某个对象有名称,那么移动并不总是安全的,因为移动后可以访问“从”对象
std::move
是一种告诉编译器您知道自己在做什么,并且事后不会访问对象(或者事后访问对象是安全的)的方法。另外,如果在ctor初始值设定项列表中
std::move
,则应注意在主体中使用类成员,而不是ctor参数。当我最多只传递具有非平凡构造函数的对象时,我使用选项2。如果我有多个具有非平凡构造函数的对象,则使用选项1。如果用户将
常量&
字符串传递给
&
构造函数,会发生什么情况?我想它会创造一个副本。然后可以将该副本移动到
std::string
成员中。@deft\u code:这不会编译。rvalue ref参数将只接受rvalue。重载解析将选择采用
常量std::string&
的构造函数。不能显式地选择构造函数。根据传递给构造函数的参数,通过重载解析获得所需的内容。