当前位置:  开发笔记 > 编程语言 > 正文

使用std :: function和std :: bind来存储回调并处理对象删除.

如何解决《使用std::function和std::bind来存储回调并处理对象删除.》经验,为你挑选了1个好方法。

我想实现一个管理器,它使用C++ 11将回调存储到多态类的成员函数中.问题是我不知道如何处理成员所属的对象被删除或应该被删除的情况,我想让界面尽可能简单.

所以我想到了以下内容:将a存储std::weak_ptr到对象以及存储std::function到成员.

以下似乎有效:

class MyBase {
public:
    MyBase() {}
    virtual ~MyBase() {}
};
//--------------------------------------------------

class MyClass : public MyBase {
public:
    MyClass() : MyBase() {}
    void myDouble(double val) const { std::cout << "Value is: " << val << std::endl; }
};
//--------------------------------------------------

Class Manager {
public:
    void setFunction(std::weak_ptr base, std::function func) {
        m_function.first  = base;
        m_function.second = func;
    }
private:
    std::pair, std::function> m_function;
};

要使用它:

Manager db;
std::shared_ptr myClass = std::make_shared();
db.setFunction(myClass, std::bind(&MyClass::myDouble, myClass, std::placeholders::_1));

现在我想隐藏std::bind用户的部分,这样他只需要调用:

db.setFunction(myClass, &MyClass::myDouble);

所以我想在我的经理函数中得到几乎以下的工作:

void setFunc2(std::weak_ptr base, std::function func) {
    m_function.first  = base;
    m_function.second = std::bind(func, base, std::placeholders::_1);
}

但上面给出了错误:

error: no match for 'operator=' (operand types are 'std::function' and 
'std::_Bind_helper&, std::weak_ptr&, const std::_Placeholder<1>&>::type {aka std::_Bind(std::weak_ptr, std::_Placeholder<1>)>}')
         m_function.second = std::bind(func, base, std::placeholders::_1);

有没有更好的方法来做到这一点,或者可能是一种方法来实现这一点?

我注意到一些有趣的东西.如果我使用原始代码中的调用增加std::shared_ptruse_count()gets std::bind.因此我无法手动重置/销毁对象,除非我取消了我的经理上的成员.这种行为记录在哪里,我通常使用cppreference?

我已经看了下面的问题,但似乎无法让它适用于我的问题:我如何使用std :: function的多态?



1> T.C...:

模板,setFunction以便您可以接受指向成员的指针,并且不必为cv/ref限定符的组合编写12次重载.

template
void setFunction(const std::shared_ptr &sp, F D2::* member) {
    // optionally static_assert that D2 is a base of D.
    m_function.first  = sp;
    m_function.second = std::bind(member, sp.get(), std::placeholders::_1);
}

显然你需要lock() m_function.first在打电话之前确认你m_function.second.

或者,只需使用捕获weak_ptr和成员函数指针的lambda :

std::function m_function;

template
void setFunction(const std::shared_ptr &sp, F D2::* member) {
    std::weak_ptr wp = sp;
    m_function = [wp, member](double d) {
        if(auto sp = wp.lock()){
             ((*sp).*member)(d);
        }
        else {
             // handle pointer no longer valid case.
        }
    };
}

推荐阅读
手机用户2502851955
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有