我在一个C++程序中有一个std::list,它包含一个A类的对象。我在另一个数据结构ref_6中存储了对第6个对象的引用,假设我需要从列表中删除第8个元素。为此,我将使用pop_front 8次并将8个对象存储在一个向量中,并使用push_front 7次将前7个元素重新插入列表中,因此现在我得到的列表将有9个元素。现在,当我试图访问存储在ref_6中的对象时,这是第六个元素,我不能这样做。在这个引用中有一些无用的值。我假设当我执行弹出和推送时,相同对象的内存位置会发生变化。我该如何处理这件事?
发布于 2010-09-05 15:55:49
你为什么要用这种方式删除东西呢?D:它不是一个堆栈。列表的全部要点(也是唯一的一点*)是,您可以在固定时间内删除任何元素。(尽管找到它是线性的。)
只需执行以下操作:
typedef std::list<T> list_type;
list_type mylist; // populate it
list_type::iterator iter = mylist.begin();
std::advance(iter, 8); // move to 8th item
mylist.erase(iter); // erase it并且不会使其他迭代器无效。(实际上,擦除一个元素会使对它的任何引用失效。)
*你可能甚至不应该使用列表。当涉及到学习数据结构时,列表是很好的,但它们非常糟糕。
发布于 2010-09-05 15:58:27
该列表将其元素存储在不连续的内存块中,当从列表中删除该元素时会释放这些内存块。因此,引用(简单地实现为指针)指向其内存已被释放的元素。
从列表中删除给定元素的更简单方法是让迭代器指向该元素并使用方法
std::list::iterator = /*somehow get the iterator to the 8th element*/
yourList.erase(8th_element_iterator);
例如,第一步(将迭代器放到第8个元素)可以通过获取列表开始的迭代器并将其向前推进7个位置来完成:
std::list::iterator first_iter = yourList.begin();
std::list::iterator 8th_iter = std::advance(first_iter, 7);
发布于 2010-09-05 18:50:44
这里有股可疑的味道。您正在按值将T类型的对象存储在std::list<T>中。您可以在其他位置保留对这些对象的引用。对吗?如果是,我看到了几个问题...许多对列表的操作可能会使存储的引用无效,因为std::list<T>只保证类型为T的元素的值的顺序。如果希望在多个位置存储对这些元素的引用,请使用std::tr1::shared_ptr<T>和std::list<std::shared_ptr<T> >。然后,您可以安全地删除或添加(甚至重新定位)列表中的元素,而保留在其他位置的引用仍然有效。当心存储std::list<T>iterators,问题也是一样的。
https://stackoverflow.com/questions/3645353
复制相似问题