2015-04-06 68 views
1

我有用户定义的类是这样的:std :: list remove_if删除节点?

class Test { 
public: 
    bool opeatator== (const Test& rhs) const { 
     return this->value_ == rhs.value_; 
    } 
    int value_; 
}; 

我保存这个终场前的std ::名单如下:

std::list<Test*> tests_; 
tests_.push_back(new Test()); 

然后我试图刚刚从列表中删除节点是这样的:

Test remove_key(1); 
tests_.remove_if([remove_key](const Test* p) { return remove_key == *p; }); 

它删除value_为1的所有节点,但是remove_if call :: operator delete()会删除列表中的对象。 据我所知,remove_if只是从列表中删除,但它不会删除对象,但是当我调试它时,列表调用析构函数的Test类,并删除对象::operator delete(_Ptr)。 我错了什么?

(以下代码是STL列表的remove_if调用堆栈(反向顺序)在Visual Studio 2013年)

列表

remove_if(_Pr1 _Pred) { 
    for (iterator _First = begin(); _First != end();) 
     if (_Pred(*_First)) 
      _First = erase(_First); 
     else 
      ++First; 
} 

iterator erase(const_iterator _Where) { 
    _Nodeptr _Pnode = _Unlinknode(_Where++); 
    this->_Freenode(_Pnode); 
    return (_Makie_iter(_Where)); 
} 

void _Freenode(_Nodeptr _Pnode) { 
    this->_Getal().deallocate(_Pnode, 1); 
} 

void deallocate(pointer _Ptr, size_type _Count) { 
    _Mybase::deallocate(_Ptr, _Count); 
} 

void deallocate(pointer _Ptr, size_type) { 
    ::operator delete(_Ptr); 
} 
+1

您认为节点从列表中移除后,它在哪里?它不会删除指针所指向的'Test'对象,如果这就是你所要求的。 – 2015-04-06 10:50:32

回答

2

但是当我调试它,测试类的列表调用析构函数

不,它不需要。而是你的析构函数被调用,因为

  1. 您已经创建了一个范围的变量remove_key,其析构函数时将作用域出
  2. 你拉姆达的价值捕获remove_key会被自动调用,所以当栈从拉姆达展开时,将调用remove_key的析构函数。

在单独的上下文中,您突出显示的代码专门用于除去链接列表的节点,而不是删除Test对象。

所以

void deallocate(pointer _Ptr, size_type) { 
    ::operator delete(_Ptr); 
} 

删除存储的指针测试链接列表的节点。

0

它重新分配该列表中的节点,而不是对象本身。如果你删除一个节点

   Node 
       +--------+ +------+ 
iterator --> | Test* -+--> | Test | 
       +--------+ +------+ 

Test将无法​​访问。

如果您有什么特别的理由使用动态分配,那么我推荐使用std::shared_ptr<Test>

+0

std :: shared_ptr在这里不需要 - std :: unique_ptr就足够了。 – 2015-04-07 01:32:29