std::list remove_if 删除节点?
std::list remove_if deletes nodes?
我有这样的用户定义class:
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; });
它删除所有 value_ 为 1 的节点,但是 remove_if 调用 ::operator delete() 所以列表中的对象被删除。
据我所知,remove_if 仅从列表中删除但不会删除对象,但是当我调试它时,列表调用 Test class 的析构函数,并通过 ::operator delete(_Ptr)
删除对象。
我哪里错了?
(以下代码是 Visual Studio 2013 中的 STL 列表 remove_if 调用堆栈(倒序)。)
列表
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);
}
它释放列表的节点,而不是对象本身。
Node
+--------+ +------+
iterator --> | Test* -+--> | Test |
+--------+ +------+
Test
删除节点将无法访问
如果您有任何特殊原因需要使用动态分配,那么我建议使用 std::shared_ptr<Test>
。
but when I debug it, list call destructor of Test class
不,不是。相反,你的析构函数被调用是因为
- 您已经创建了一个作用域变量
remove_key
,它的析构函数将在作用域外时自动调用
- 您的 lambda 按值捕获
remove_key
,因此当堆栈从 lambda 展开时,将调用 remove_key
的析构函数。
在单独的上下文中,您突出显示的代码专门用于删除 link 列表的节点,而不是删除 Test 对象。
所以
void deallocate(pointer _Ptr, size_type) {
::operator delete(_Ptr);
}
删除了 link 列表中存储指向 Test 的指针的节点。
我有这样的用户定义class:
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; });
它删除所有 value_ 为 1 的节点,但是 remove_if 调用 ::operator delete() 所以列表中的对象被删除。
据我所知,remove_if 仅从列表中删除但不会删除对象,但是当我调试它时,列表调用 Test class 的析构函数,并通过 ::operator delete(_Ptr)
删除对象。
我哪里错了?
(以下代码是 Visual Studio 2013 中的 STL 列表 remove_if 调用堆栈(倒序)。)
列表
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);
}
它释放列表的节点,而不是对象本身。
Node
+--------+ +------+
iterator --> | Test* -+--> | Test |
+--------+ +------+
Test
删除节点将无法访问
如果您有任何特殊原因需要使用动态分配,那么我建议使用 std::shared_ptr<Test>
。
but when I debug it, list call destructor of Test class
不,不是。相反,你的析构函数被调用是因为
- 您已经创建了一个作用域变量
remove_key
,它的析构函数将在作用域外时自动调用 - 您的 lambda 按值捕获
remove_key
,因此当堆栈从 lambda 展开时,将调用remove_key
的析构函数。
在单独的上下文中,您突出显示的代码专门用于删除 link 列表的节点,而不是删除 Test 对象。
所以
void deallocate(pointer _Ptr, size_type) {
::operator delete(_Ptr);
}
删除了 link 列表中存储指向 Test 的指针的节点。