如何在不相关的类之间传递C++回调?

2024-01-25

在非升压项目中,我有一个类,它使用基于特定用户操作(按下/释放按钮)的计时器。我希望此类具有通用性,因此它需要回调用户定义的操作。

// 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,但无法将函数指针传递给回调函数。这些功能不是静态的。编译器最终抱怨:

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

一些对此的研究指出std::function() and std::bind()但我对这些并不熟悉,希望得到一些有关如何解决此问题的指示。

解决:对于任何感兴趣的人,这里是最终解决方案的组成部分

// 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));

老式的方法是让你的回调函数接受一个额外的void*参数,您可以为其传递一个指向要调用该函数的对象的指针。然后,您对回调使用静态成员函数,并让它将指针转换为正确的对象并调用真正的回调。

typedef void (*timerCallback)(void*);
...
void setCallbackShortTime(timerCallback clickFn, void* object) { shortCallback = clickFn; shortCallbackObject = object;} ;
void setCallbackLongTime(timerCallback clickFn, void* object) { longCallback = clickFn; longCallbackObject = object;} ;
...

static void openLiveViewWindowCallback(void* object) { ((CMyDlg*)object)->openLiveViewWindow(); }
void openLiveViewWindow();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在不相关的类之间传递C++回调? 的相关文章

随机推荐