对无效实例的引用是什么?

ale64bit

我有一个存储一些数据的类,还有一个需要修改一些父类数据的成员。考虑以下简化示例:

#include <iostream>
#include <vector>
#include <string>

struct Modifier {
  std::vector<std::string> &stuff;

  Modifier(std::vector<std::string> &ref) : stuff(ref) {}
  void DoIt() {
      std::cout << "stuff.size = " << stuff.size() << '\n';
  }
};

struct Container {
  std::vector<std::string> stuff;
  Modifier modifier;

  std::vector<std::string> BuildStuff(int n) {
      return std::vector<std::string>{"foo", std::to_string(n)};
  }
  Container(int n) : stuff(BuildStuff(n)), modifier(stuff) {}
};

int main()
{
  std::vector<Container> containers;
  containers.emplace_back(5);
  containers.emplace_back(42);
  containers[0].modifier.DoIt();
  containers[1].modifier.DoIt();
  return 0;
}

当我运行它时,其中一个放置的实例正确报告 size 2,但另一个报告 size 0我认为由于 emplaceing 会发生一些未定义的行为,但我无法确定根本原因是什么。

另外,有没有更优雅的方式来表示这种情况?

现场示例:http : //coliru.stacked-crooked.com/a/e68ae9bf2b7e6b75

毫米

当你做第二个时emplace_back,向量可能会经历一个重新分配操作:为了增长,它分配一个新的内存块并将对象从旧的移动到新的,并释放旧的内存块。

您的Modifier对象在移动时会生成一个悬空引用:目标对象的引用引用旧引用所做的同一对象。

要解决此问题,您可以向 中添加移动构造函数Container,然后添加或删除复制构造函数。Modifier必须被初始化来表示Container它是一个成员; 但是默认的复制和移动构造函数将初始化Modifier以引用被复制/移动的源。

例如:

Container(Container&& o) : stuff(std::move(o.stuff)), modifier(stuff) {}
Container(Container const& o) : stuff(o.stuff), modifier(stuff) {}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章