首页 文章

std :: list remove_if删除节点?

提问于
浏览
1

我有这样的用户定义的类:

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 call :: operator delete()删除列表中的对象 . 据我所知,remove_if只从列表中删除但它不会删除对象,但是当我调试它时,列出Test类的调用析构函数,并通过 ::operator delete(_Ptr) 删除该对象 . 我错了什么?

(下面的代码是Visual Studio 2013中的STL列表remove_if callstack(反向顺序) . )

名单

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

2 回答

  • 0

    但是当我调试它时,列出Test类的调用析构函数

    不,不 . 而是你的析构函数被调用,因为

    • 您已经创建了一个范围变量 remove_key ,它的析构函数将在作用域时自动调用

    • 你的lambda按值捕获 remove_key 所以当堆栈从lambda展开时,将调用 remove_key 的析构函数 .

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

    所以

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

    删除了存储指向Test的指针的链接列表的节点 .

  • 2

    它释放列表的节点,而不是对象本身 .

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

    如果删除节点,将无法访问 Test .

    如果您有任何特殊原因要使用动态分配,那么我建议使用 std::shared_ptr<Test> .

相关问题