【问题标题】:How do I have a class hold an array of itself by using STL containers/smart pointers?如何让一个类通过使用 STL 容器/智能指针来保存一个自身的数组?
【发布时间】:2018-05-11 08:28:16
【问题描述】:

所以我基本上想这样做:

struct A {

    A *children[10];
};

但是,当我这样做并创建一个析构函数时,例如:

 virtual ~A() {
        for (A *child: children) {
            delete child;
        }
    }

我遇到了分段错误,但我不知道为什么。那么如何使用 STL 类完成在 A 中保存 A 的列表,这样我就不必担心 new/delete 了?我尝试了矢量并得到一个“不完整类型”的错误。

【问题讨论】:

  • 你试过std::vector<A*>吗?我不认为A 曾经包含它自己?我只是在这里猜测,因为这里没有足够的信息可以做任何事情。考虑 editing 您的问题包含 minimal reproducible example,对于您的示例,它不应超过大约 20 行。
  • C++17 你可以写struct A { std::vector<A> children; };没有这些不完整类型的担忧。这可能不会立即有帮助,但如果您的系统允许,升级到最新标准会有所帮助:)
  • 在此处显示的代码中,指针尚未初始化,因此每次删除都会产生未定义的行为。
  • 您的第一个循环“按值”迭代。它不会改变 a.get()->children 数组,这与您显然相信的相反。
  • 回滚,你不能在得到答案后就问一个新问题来代替旧问题。问一个新问题。

标签: c++ oop c++11 stl std


【解决方案1】:

所以

  1. for (A *child: A) { delete child; ... 中,您可能应该迭代children,而不是A
  2. 要使上述方法起作用,您应该将您的孩子存储在 std::vector 中,而不是原始数组 (std::vector<A> children)。
  3. 使用您选择的smart pointer(如std::shared_ptr)而不是原始指针,那么您不必删除任何内容。

【讨论】:

  • 谢谢,我知道如何使用 stl 容器,但是遇到了初始化问题,请参阅更新的问题
  • @BeardMagician 不要将问题更改为完全不同的问题。而是提出一个新问题。
【解决方案2】:

这个:

for (shared_ptr<A> child: a.get()->children) {

不遍历children——它遍历children中指针的副本。因此,在每次迭代中,您复制(空)共享指针 (child),然后将该循环本地副本设置为新分配的对象,然后 child 超出范围并释放分配的对象。 children 数组中的指针永远不会被修改。

你想要的是:

for (shared_ptr<A> &child: a.get()->children) {

显式引用 (&amp;) 意味着在循环的每次迭代中,child 将是对 children 数组中的 shared_ptr 的引用,而不是副本。所以当你分配给它时,它会修改数组。

【讨论】:

  • 所以问题完全改变了,你的答案适合新问题,我的适合旧问题。我应该在这里做什么,回滚更改的编辑?放弃?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-03
  • 1970-01-01
相关资源
最近更新 更多