How to pass C ++ callbacks between unrelated classes?

In a project without promotion, I have a class that uses a timer based on a specific user action (the button is pressed / released). I want this class to be generic, so it accepts 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);
...

Now from another class (DialogClass) I can use TimerClass, but I can not pass pointers to callback functions. These functions are not static. The compiler complains:

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

In some studies, this pointed to std::function()and std::bind(), but I am not familiar with them and would like to evaluate some ways to solve this problem.

PERMISSION . For anyone interested, here are the bricks of the final decision

// 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));
+5
4

std::function - , . , , :

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

std::bind , . -, , :

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

, 2011 , . Boost TR1 , --, / , .

+2

, 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();
+3

, . std::function(), VS2010, . ( ) , .

+2

, .

class TFunctorBase
{
public:
    TFunctorBase(void) {}
    virtual ~TFunctorBase(void) {}
    virtual void operator()(void) = 0;
};

// derived template class
template <class TClass> class TFunctor : public TFunctorBase
{
private:
    void (TClass::*fpt)();   // pointer to member function
    TClass* pt2Object;                  // pointer to object

public:
    TFunctor(TClass* _pt2Object, void(TClass::*_fpt)())
    { pt2Object = _pt2Object; fpt = _fpt;};

    virtual void operator()(void)
    { (*pt2Object.*fpt)();};              // execute member function
};

To initialize a functor object:

TFunctor<MyClass> obj(&myInstance, &MyClass::myMemberFunction);

And use it:

(*obj)(); 
//(*obj)(42); for operator()(int)

Here is an example:

class ClassA
{
public:
   void function1(int a, string b);
};

ClassA objA;
TFunctor<ClassA> functor(&objA,&ClassA::function);
(*functor)(42, "pumpkin"); //assuming you added virtual void operator()(int, string) to TFunctorBase

Here is a great resource on functors along with the implementation described above. http://www.newty.de/fpt/functor.html#chapter4

+1
source

All Articles