如何在不相关的类之间传递C ++回调? [英] how to pass C++ callbacks between unrelated classes?

查看:139
本文介绍了如何在不相关的类之间传递C ++回调?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在非boost项目中,我有一个类,它使用基于某个用户操作的定时器(按下/释放按钮)。我想这个类通用,所以它需要回调用户定义的操作。

In a non-boost project, I have a class which uses a timer based on a certain user action (button pressed/released). I want this class generic, so it takes callbacks for user defined actions.

// TimerClass.h
typedef void (*timerCallback)(void);
...
Class TimerClass : public CButton {
public:
    void setCallbackShortTime(timerCallback clickFn) { shortCallback = clickFn;} ;
    void setCallbackLongTime(timerCallback clickFn) { longCallback = clickFn;} ;
private:
    timerCallback shortCallback, longCallback;
}


// CMyDlg.h
class CMyDlg : public CDialog
{
public:
    void openLiveViewWindow();
    void openAdminPanelWindow();
    TimerClass _buttonSettings;
}

// CMyDlg.cpp
...
_buttonSettings.setCallbackShortTime(&openLiveViewWindow);
...

现在,从另一个类(DialogClass),我可以使用TimerClass,我不能传递函数指针到回调函数。这些函数不是静态的。编译器最终抱怨:

Now, from another class (DialogClass) I can use the TimerClass but I cannot pass function pointers to the callback functions. These functions are not static. The compiler ends up complaining:

error C2276: '&' : illegal operation on bound member function expression

一些研究指出 std :: function() std :: bind()但我不熟悉这些,并将感谢一些指示如何解决这个。

Some research on this pointed out to std::function() and std::bind() but I'm not familiar with these and would appreciate some pointers on how to resolve this.

解决方案:对于感兴趣的人,这里是最终解决方案的砖块

RESOLUTION: For anyone interested, here are the bricks of the final solution

// TimedButton.h
#include <functional>
// define timer callback prototype
typedef std::function<void()> timerCallback;
...
class TimedButton : public CButton
{
public:
    TimedButton();
    ...
    void setCallbackShortTime(timerCallback clickFn) { _shortCallback = clickFn;} ;
    void setCallbackLongTime(timerCallback clickFn) { _longCallback = clickFn;} ;
private:
    timerCallback _shortCallback;
    timerCallback _longCallback;
}

// TimedButton.cpp
...
(_longCallback)();  // call long duration fn
...
(_shortCallback)();     // call short duration fn

// in MyDlg.cpp
#include <functional>
...
_buttonSettings.setCallbackShortTime(std::bind(&CMyDlg::openLiveViewWindow, this));
_buttonSettings.setCallbackLongTime(std::bind(&CMyDlg::openAdminPanelWindow, this));


推荐答案

std :: function 是一个多态函数对象,它可以包装任何类型的具有特定签名的可调用对象。在你的case,你希望它没有参数,并且不返回任何值,所以你可以定义:

std::function is a polymorphic function object, which can wrap up any type of callable object with a particular signature. In your case, you want it to take no arguments and return no value, so you can define:

typedef std::function<void()> timerCallback;

std :: bind 将可调用对象绑定到不同签名中的一个,通过将参数绑定到参数。在你的情况下,你想通过绑定一个成员函数到一个特定的对象来调用它:

std::bind allows you to adapt a callable object to one of a different signature, by binding arguments to parameters. In your case, you want to adapt a member function by binding it to a particular object to invoke it on:

_buttonSettings.setCallbackShortTime(std::bind(&CMyDlg::openLiveViewWindow, this));

请注意,这些是在2011年引入的,因此旧的编译器不会支持它们。在这种情况下,你可以使用非常相似的Boost或TR1库,或者使你自己的可调用类包含一个指向成员函数的指针或指向你要调用的对象的指针/引用。

Note that these were introduced in 2011, so older compilers won't support them. In that case, you could either use the very similar Boost or TR1 libraries, or make your own callable class containing a pointer-to-member-function and a pointer/reference to the object you want to invoke it on.

这篇关于如何在不相关的类之间传递C ++回调?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆