从工厂函数返回右值引用时堆/内存损坏

时间:2014-10-11 00:00:45

标签: c++ c++11 move-semantics

我有一个类似的课程:

class CObj
{
public:
   CObj(std::string const& str) : m_str(str) {}

   static CObj&& Current()
   {
      CObj uxid{"test"};
      return std::move(uxid);
   }

private:
   std::string m_str;
};

我这样使用它:

CObj obj{CObj::Current()};

std::string内的obj已损坏/无效。我希望将临时工厂搬出工厂并进行初始化obj。我做错了什么?

1 个答案:

答案 0 :(得分:3)

Current的返回类型是引用类型。您将返回对本地对象的引用,该对象将在被调用者尝试访问它以构造obj之前销毁,从而导致未定义的行为。返回类型是右值引用的事实与此事实无关,问题与左值引用返回类型相同。

如果要从函数返回新创建的对象,则应按值返回:

static CObj Current() {
  return {"test"};
}

或:

static CObj Current() {
  CObj uxid{"test"};
  // do stuff with uxid here.
  return uxid;
}

按值返回的本地将自动移动,尽管编译器更有可能应用返回值优化并直接在返回值中构造对象而不进行任何移动或复制。