gpt4 book ai didi

c++ - 对已失效的已放置实例的引用是什么?

转载 作者:行者123 更新时间:2023-11-27 23:44:30 24 4
gpt4 key购买 nike

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

#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;
}

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

此外,是否有更优雅的方式来表示这种情况?

实例:http://coliru.stacked-crooked.com/a/e68ae9bf2b7e6b75

最佳答案

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

您的 Modifier 对象在移动时会生成悬空引用:目标对象的引用与旧引用引用的对象相同。

要解决此问题,您可以向 Container 添加移动构造函数,然后添加或删除复制构造函数。 Modifier 必须初始化以引用它所属的 Container;但默认的复制和移动构造函数将初始化 Modifier 以引用要从中复制/移动的源。

例如:

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

关于c++ - 对已失效的已放置实例的引用是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51717780/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com