【问题标题】:Basic questions about std::list关于 std::list 的基本问题
【发布时间】:2013-04-20 12:01:57
【问题描述】:

我想使用list 来保存一系列对象,这些对象包含有关我将执行的任务的信息。一旦这些对象之一完成,我就不再需要它;我只需要转到列表中的下一个对象。这基本上是一个队列。

关于指向这些对象的指针:

一旦我得到一个指向要操作的列表对象的指针,如果我删除列表中的其他元素,这个指针仍然有效,对吗?因为一旦我完成了我的第一个对象,我将移动到下一个对象,我将 pop 第一个对象,同时我继续处理下一个对象,它现在成为第一个对象。本质上,我将始终处理列表中的第一个对象。我想确保即使我删除了其他列表项,指向现有列表项的指针也不会失效。

(顺便说一句,这是我想使用list 的主要原因,因此我可以操作它而无需将所有其他列表对象潜在地移动到内存中的新空间,就像vector 的情况一样这会让这个变得昂贵)

关于记忆:

当我向列表中添加某些内容时,我是否可以期望列表获得所有权,并且如果我的原始项目超出范围而列表仍在成员变量范围内,我的对象仍将保留吗?然后,一旦弹出,item对象最终会超出范围吗?

【问题讨论】:

  • 如果你要将它用作队列,那么为什么不使用std::queue
  • @JoachimPileborg 我的读数表明 list 是最好的,如果您在遍历它的同时对其进行操作。

标签: c++ list containers


【解决方案1】:

一旦我得到一个指向要操作的列表对象的指针,如果我删除列表中的其他元素,这个指针仍然有效,对吗?

是的,因为指向 std::list 的指针不是指向普通双链表头元素的指针 - std::list 类具有内部指针,它使它们远离用户(您可以使用迭代器迭代列表,但不使用普通指针)。

当我向列表中添加某些内容时,我是否可以期望列表获得所有权,并且如果我的原始项目超出范围而列表仍在成员变量范围内,我的对象仍将保留吗?然后,一旦弹出,item对象最终会超出范围吗?

您需要创建std::list<T> 而不是std::list<T*>。这样,当你将元素添加到列表中时,将调用复制构造函数,并将对象的副本放入列表中,而不是实际的对象。

【讨论】:

    【解决方案2】:

    如果我删除列表中的其他元素,这个指针仍然有效,对吧?

    是的,列表元素的迭代器仍然有效,除非您从列表中显式删除元素或清除列表。

    当我向列表中添加某些内容时,我是否可以期望列表获得所有权?如果我的原始项目超出范围而列表仍在成员变量范围内,我的对象仍将保留?

    是的,有点。该列表复制您推入其中的元素。它并没有真正获得所有权,而是创建了一个它拥有的新对象。

    然后,一旦弹出,item对象最终会超出范围吗?

    是的,该对象将不复存在。

    请注意,如果您将指针传递给对象,则所有赌注都将关闭。在这种情况下,列表只控制它所持有的指针的生命周期,而不是它们指向的对象。

    【讨论】:

    • 如果我在for 循环中使用iterator 并且我在iterator 的当前迭代中使用erasefor 循环应该继续正常并访问其余部分的list 元素?
    • @SebbyJohanns 问题是当您执行for(iter=...; iter!=end; ++iter) list.erase(iter); 时,擦除将使iter 无效,因此以下增量在技术上是无效的。不过,您可以做的是for(iter=...; iter!=end; iter=list.erase(iter))for(iter=...; iter!=end; ) if(to_erase) iter = list.erase(iter); else ++iter;,具体取决于您的特定需求(部分擦除与整体擦除,尽管对于整体擦除list.clear() 无论如何都会容易得多)。
    • @ChristianRau 很好,先生,您是一位学者一位绅士,我很感激!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多