2015-04-06 2 views
1

У меня есть определенный пользователем класс, как это:std :: list remove_if удаляет узлы?

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

Я сохранил этот указатель с станд :: список, как это:

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). Что я не так?

(Ниже код список СТЛ 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', на который указывает указатель, если это то, о чем вы просите. –

ответ

2

, но когда я его отладки, список вызовов деструктора класса Test

Нет, это не так. Скорее всего ваш деструктор, потому что

  1. Вы создали Scoped переменную 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 будет достаточно. –

Смежные вопросы