如何检测传递给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()将崩溃,因为std::function的实例之一不存在。

所以我的问题-有什么方法可以防止这种情况?如何检测该实例已被删除,如何安全地从列表中删除此类std::function

解决方法

有什么方法可以防止这种情况吗?

从列表中删除功能之前,销毁该功能正在使用的对象。

如何检测实例已被删除,如何安全地从列表中删除此类std :: function?

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

如果您真的想检测对象是否存在,请将对象包装在std::shared_ptr中,然后将std::weak_ptr与使用它的函数一起存储到该对象。然后,您可以在调用函数之前查询std::weak_ptr。或者,改为存储std::shared_ptr,并在调用该函数之前查询其refcount> 1。

,

您在通常称为RAII pattern

中使用C ++构造函数和析构函数
class MySingleton
{
public:
    static MySingleton &instance()
    {
        static MySingleton inst;
        return inst;
    }

    int addFunc(const std::function<void(void)> &func)
    {
        int nKey = m_nKey++;
        m_mapfunc.emplace(nKey,func);
        return nKey;
    }

    void removeFunc(int nKey) {
        m_mapfunc.erase(nKey);
    }

protected:
    void periodicallyCalled()
    {
        for(auto pairnfn: m_mapfunc)
        {
            pairnfn.second();
        }
    }

private:
    int m_nKey = 0;
    std::unordered_map<int,std::function<void(void)>> m_mapfunc;
};

class Test
{
public:
    Test() : m_nKey(
      MySingleton::instance().addFunc(std::bind(&Test::test,this,std::placeholders::_1))
    ) 
    {}

    ~Test() {
      MySingleton::instance().removeFunc(m_nKey);
    }
    void test()
    {
        somenum ++;
    }
protected:
    int m_nKey;
    int somenum = 0;
}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...