c ++ 11的"移动工厂"

Ide*_*Hat 1 c++ move-semantics

我想创建一个工厂样式生成器,它接收A并输出A,RA的子类(它向A添加信息).我不能想到一个安全的方法来做到这一点.

结构体:

class A
{
public:
  std::string str;
  A(std::string a)
  {
    str = a;
  }
  A(A&& a) :
    str(std::move(a.str))
  {
  }
};

class AR : public A
{
public:
  std::string str1;
  AR(std::string a,std::string b) : A(a)
  {
    str1 = b;
  }
  AR(A &&a,const std::string& b)
    : A(std::forward<A>(a))
  {
    str1 = b;
  }
  AR(AR&& ar)
    : A(std::forward<A>(ar)),
    str1(std::move(ar.str1))
  {
  }
};

class ARFactory;
Run Code Online (Sandbox Code Playgroud)

最安全的方式可能是

  AR GenerateRA1(A&& a)
  {
    return AR(std::forward<A>(a),std::string("foo"));
  }
Run Code Online (Sandbox Code Playgroud)

这将强制a被破坏.问题是,这会导致用户在函数调用之前无法以任何方式使用a的参数,这可能很烦人:

ARFactory fact;
{
  AR ar=fact.GenerateRA1(A("bar"));//compiles
}
{
  A a("bar");
  a.str += "1";
  //AR ar = fact.GenerateRA1(a);//doesn't compile
  AR ar = fact.GenerateRA1(std::move(a));//does...reference to a is still around, but destroyed
  std::cout << "a.str=" << a.str << " b.str=" << ar.str << " ar.str1=" << ar.str1 << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

这个可以吗?我可以看到对"a"的调用非常糟糕而没有构建检查以查看对象是否已被破坏.

Dav*_*eas 5

AR ar = fact.GenerateRA1(std::move(a));//does...reference to a is still around, but destroyed
Run Code Online (Sandbox Code Playgroud)

用户要求内容移出a函数,她知道a可能已移动的内容并知道A她知道该对象可以做什么或不做什么的类型a.这不是问题,这就是事情的运作方式.

//AR ar = fact.GenerateRA1(a); //doesn't compile
Run Code Online (Sandbox Code Playgroud)

这正是主要观点.编译器拒绝此代码,因此用户无需检查是否a移出(*),仅当用户明确请求移动(因此知道而不必猜测)时,编译器将移出宾语.