C++ 11 的"Move Factory"

"Move Factory" for c++ 11

本文关键字:Move Factory C++      更新时间:2023-10-16

我想做一个工厂风格的生成器,它接受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;

最安全的方法可能是

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

这将强制 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;
}

可以吗?我可以看到对"a"的调用在没有内置检查以查看对象是否已被破坏的情况下变得非常错误。

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

用户请求您将内容a移动到函数中,她知道a的内容可能已被移动,并且知道类型A她知道对象可以做什么或不可以做什么a。这不是问题,这就是事情的运作方式。

//AR ar = fact.GenerateRA1(a); //doesn't compile

这正是重点。编译器拒绝此代码,因此用户不需要检查a是否移出 (*(,只有当用户显式请求移动(因此无需猜测即可知道(编译器将移出对象时。