2015-04-06 102 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