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

标签 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()};

obj 中的 std::string 已损坏/无效。我希望从工厂中 move 临时文件并 move 初始化 obj。我做错了什么?

最佳答案

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

如果你想从一个函数中返回一个新创建的对象,你应该按值返回它:

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

或:

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

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

关于c++ - 从工厂函数返回右值引用时堆/内存损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26309663/

相关文章:

c++ - 使用 std::move 和 std::shared_ptr 有什么好处和风险(如果有的话)

c++ - _mm_extract_epi8(...) intrinsic 以非文字整数作为参数

c++ - 将类型添加到现有模板中,但不删除c++ 17

c++ - 如何在 C++ 中使用来自 dll 的结构?

c++ - 如何优化获取数组中的最大值?

c++11 - 用户声明的隐式声明的 move 赋值运算符意味着什么?

c++ - 为什么 move 赋值运算符应该返回对 *this 的引用

c++ - 如何检测DTLS中收到的消息?

c++ - 这个样本中的 vector 是否被复制了两次?

c++ - 在 C++11 中有零大小的 std::array 的原因吗?