【问题标题】:std::list pop and erase method fails to destroy the removed itemstd::list 弹出和擦除方法无法销毁已删除的项目
【发布时间】:2013-10-02 02:37:07
【问题描述】:

关于 http://www.cplusplus.com/reference/list/list/erase/ 的描述,我明白了

   This effectively reduces the container size by the number of elements removed,
which are destroyed.

pop 方法的类似描述。

但在我对 VS2012 的测试中,删除的项目并没有被破坏。我对此感到困惑。

这是我的测试代码。我仍然可以从 std::list 擦除的内存中输出,我认为这是错误的。

#include <stdio.h> 
#include <list>
using namespace std;
class test
{
public:
   int a;
   test() {a = 111;}
};
int main(void)
{
   list<test*> l;
   test* t = new test;
   l.push_back(t);
   l.erase(l.begin());
   printf("%d\n", t->a);

   return 0;
}

【问题讨论】:

  • 也许您应该先学习基础知识(指针的含义等),然后再使用 std::list 这样的“高级”功能?
  • 你期望你的错误代码会发生什么?如果您期待某种错误消息或崩溃,那么恐怕您会对 C++ 感到非常失望。大多数错误会导致 Undefined Behaviour,这意味着实际上任何事情都可能发生。

标签: c++ list std


【解决方案1】:

项目被销毁,也就是说它的析构函数被调用。唉,指针的析构函数什么都不做。特别是,它不会删除指向的对象。

请记住,与 Java 和 C# 不同,C++ 对所有事物都有值语义,而指针和引用是您必须始终自己处理的显式构造。所以销毁指针和删除指向的对象是不同的操作。

如果你有 C++11,std::unique_ptris usable in list 将确保删除指向的对象,但它不可复制以强制执行正确的内存管理。如果需要复制,可以使用(也是C++11)std::shared_ptr,可以复制,但是有一些运行时开销。

如果你没有 C++11,你可以使用Boost.PointerContainerboost::shared_ptr

当然,在大多数情况下,您一开始就不应该使用间接。在适用的情况下,在 C++ 中首选按值操作对象。值得注意的是,它不适用于多态对象,但实际上它们在 C++ 中并不常见。

【讨论】:

  • 我会添加更好的解决方案,在许多情况下,根本不使用任何类型的指针。我知道这只是测试代码,但 list&lt;test&gt; 必须是一个选项。
猜你喜欢
  • 1970-01-01
  • 2015-06-13
  • 2020-07-05
  • 1970-01-01
  • 2012-03-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-22
相关资源
最近更新 更多