首页 > 解决方案 > 如何检测传递给 std::bind 的实例已破坏

问题描述

我有一个单例,其中包含一个列表std::function并定期调用它。

class MySingleton
{
public:
    static MySingleton &instance()
    {
        static MySingleton inst;
        return inst;
    }

    void addFunc(const std::function<void(void)> &func)
    {
        m_list.push_back(func);
    }

protected:
    void periodicallyCalled()
    {
        for(auto f: m_list)
        {
            f();
        }
    }

private:
    std::vector<std::function<void(void)>> m_list;
}

用法:

class Test
{
public:
    void test()
    {
        somenum ++;
    }
protected:
    int somenum = 0;
}


Test *inst1 = new Test;
auto f1 = std::bind(&Test::test, inst1, std::placeholders::_1);
MySingleton::instance().addFunc(f1);

Test *inst2 = new Test;
auto f2 = std::bind(&Test::test, inst2, std::placeholders::_1);
MySingleton::instance().addFunc(f2);

过了一会儿,我销毁了一个对象:

delete inst1;

并且periodicallyCalled()会崩溃,因为 s 点之一的实例std::function不存在。

所以我的问题 - 有什么方法可以防止这种情况发生吗?我怎样才能检测到该实例已被删除,并且我可以安全地std::function从列表中删除它?

标签: c++std-function

解决方案


有什么办法可以防止这种情况发生吗?

在销毁该函数正在使用的对象之前从列表中删除该函数。

如何检测到该实例已被删除,并且我可以从列表中安全地删除此类 std::function?

你不能。至少,不是您编写代码的方式。因此,首先删除该功能。

如果你真的想检测对象是否活着,将对象包装在 a 中std::shared_ptr,然后将 astd::weak_ptr与使用它的函数一起存储到它。然后你可以std::weak_ptr在调用函数之前查询。或者,存储它std::shared_ptr,并在调用函数之前查询其引用计数 > 1。


推荐阅读