fdu*_*uff 5 c++ function-pointers visual-studio-2010
在非升级项目中,我有一个类,它使用基于某个用户操作的计时器(按下/释放按钮).我希望这个类是通用的,因此需要对用户定义的操作进行回调.
// 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);
...
Run Code Online (Sandbox Code Playgroud)
现在,从另一个类(DialogClass)我可以使用TimerClass,但我无法将函数指针传递给回调函数.这些功能不是静态的.编译器最终抱怨:
error C2276: '&' : illegal operation on bound member function expression
Run Code Online (Sandbox Code Playgroud)
对此的一些研究指出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));
Run Code Online (Sandbox Code Playgroud)
std::function是一个多态函数对象,它可以用特定的签名包装任何类型的可调用对象。在您的情况下,您希望它不带参数也不返回任何值,因此您可以定义:
typedef std::function<void()> timerCallback;
Run Code Online (Sandbox Code Playgroud)
std::bind允许您通过将参数绑定到参数来使可调用对象适应不同的签名之一。在您的情况下,您希望通过将成员函数绑定到特定对象来调用它来调整成员函数:
_buttonSettings.setCallbackShortTime(std::bind(&CMyDlg::openLiveViewWindow, this));
Run Code Online (Sandbox Code Playgroud)
请注意,这些是在 2011 年引入的,因此较旧的编译器不支持它们。在这种情况下,您可以使用非常相似的 Boost 或 TR1 库,或者创建您自己的可调用类,其中包含指向成员函数的指针和指向要调用它的对象的指针/引用。