【问题标题】:std::list remove_if deletes nodes?std::list remove_if 删除节点?
【发布时间】:2015-04-06 10:43:40
【问题描述】:

我有这样的用户定义类:

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 类的析构函数,并通过::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);
}

【问题讨论】:

  • 你认为节点从列表中删除后会去哪里?它不会删除指针指向的 Test 对象,如果这就是您所要求的。

标签: c++ list c++11 stl remove-if


【解决方案1】:

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

不,它没有。而是调用您的析构函数,因为

  1. 你已经创建了一个作用域变量remove_key,它的析构函数会在作用域外被自动调用
  2. 您的 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&lt;Test&gt;

    【讨论】:

    • 这里不需要 std::shared_ptr - std::unique_ptr 就足够了。
    猜你喜欢
    • 2014-09-27
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    • 2012-02-11
    • 2011-05-27
    相关资源
    最近更新 更多