Sia*_*sou 27 c++ destructor stl list c++-faq
std::list<Node *> lst;
//....
Node * node = /* get from somewhere pointer on my node */;
lst.remove(node);
Run Code Online (Sandbox Code Playgroud)
std :: list :: remove方法是否调用每个被删除元素的析构函数(和空闲内存)?如果是,我怎么能避免呢?
fre*_*low 46
是的,Foo*从容器中删除a 会破坏Foo*,但不会释放Foo.销毁原始指针总是无操作.它不能是任何其他方式!让我举几个理由.
如果指针实际上是动态分配的,那么删除指针才有意义,但运行时如何知道指针变量被销毁时是否就是这种情况?指针也可以指向静态和自动变量,删除其中一个会产生未定义的行为.
{
Foo x;
Foo* p = &x;
Foo* q = new Foo;
// Has *q been allocated dynamically?
// (The answer is YES, but the runtime doesn't know that.)
// Has *p been allocated dynamically?
// (The answer is NO, but the runtime doesn't know that.)
}
Run Code Online (Sandbox Code Playgroud)
无法确定指针对象是否已在过去发布.删除相同的指针两次会产生未定义的行为.(它在第一次删除后变成悬空指针.)
{
Foo* p = new Foo;
Foo* q = p;
// Has *q already been released?
// (The answer is NO, but the runtime doesn't know that.)
// (...suppose that pointees WOULD be automatically released...)
// Has *p already been released?
// (The answer WOULD now be YES, but the runtime doesn't know that.)
}
Run Code Online (Sandbox Code Playgroud)
也无法检测指针变量是否已经初始化.猜猜当你试图删除这样的指针时会发生什么?再一次,答案是未定义的行为.
{
Foo* p;
// Has p been properly initialized?
// (The answer is NO, but the runtime doesn't know that.)
}
Run Code Online (Sandbox Code Playgroud)
类型系统不区分指向单个对象(Foo*)的指针和指向对象数组的第一个元素的指针(也Foo*).当指针变量被销毁时,运行时无法确定是否通过delete或通过释放指针delete[].通过错误的表单释放会调用未定义的行为.
{
Foo* p = new Foo;
Foo* q = new Foo[100];
// What should I do, delete q or delete[] q?
// (The answer is delete[] q, but the runtime doesn't know that.)
// What should I do, delete p or delete[] p?
// (The answer is delete p, but the runtime doesn't know that.)
}
Run Code Online (Sandbox Code Playgroud)
由于运行时无法对指针对象做任何事情,因此销毁指针变量始终是无操作.无所事事肯定比由于不知情的猜测导致未定义的行为更好:-)
考虑使用智能指针作为容器的值类型,而不是原始指针,因为它们负责在不再需要时释放指针.根据您的需要,使用std::shared_ptr<Foo>或std::unique_ptr<Foo>.如果你的编译器还不支持C++ 0x,请使用boost::shared_ptr<Foo>.
从来没有,我再说一遍,永远不要使用std::auto_ptr<Foo>作为容器的值类型.
Joh*_*ing 12
它调用了每个项目的析构函数list- 但这不是一个Node对象.它是一个Node*.
所以它不会删除Node指针.
那有意义吗?
它确实调用列表中数据的析构函数.这意味着,std::list<T>::remove将调用析构函数T时(这是必要的T是一样的东西std::vector).
在你的情况下,它会调用析构函数Node*,这是一个无操作.它不会调用析构函数node.