std :: list remove_if удаляет узлы?

У меня есть пользовательский класс, как это:

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

Я сохранил этот указатель с помощью std :: list следующим образом:

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; });

Он удаляет все узлы, значение которых равно 1, но вызывает remove_if call :: operator delete (), поэтому объект в списке удаляется.
Как я знаю, remove_if удаляет только из списка, но не удаляет объект, но когда я его отлаживаю, вызываю деструктор вызова класса Test и удаляю объект ::operator delete(_Ptr),
Что я не прав?

(Ниже приведен код STL-списка remove_if callstack (обратный порядок) в 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

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

  1. Вы создали переменную в области видимости remove_key , чей деструктор будет вызван автоматически, когда он будет виден
  2. Ваша лямбда захвачена remove_key по значению, поэтому при разматывании стека из лямбды, деструктор remove_key будет называться.

В отдельном контексте выделенный вами код предназначен специально для удаления узла из списка ссылок, а не для удаления объекта Test.

Так

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

удалил узел списка ссылок, в котором хранится указатель на Test.

2

Другие решения

Он освобождает узел списка, а не сам объект.

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

Test будет недоступен, если вы удалите узел.

Если у вас есть какая-то конкретная причина использовать динамическое размещение, то я рекомендую использовать std::shared_ptr<Test>,

0

По вопросам рекламы [email protected]