作者热门文章
- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
在非提升项目中,我有一个类使用基于特定用户操作(按下/释放按钮)的计时器。我想要这个类是通用的,所以它需要回调用户定义的操作。
// 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()
和 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();
关于c++ - 如何在不相关的类之间传递 C++ 回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11940209/
我是一名优秀的程序员,十分优秀!