0

I have a series of callbacks, that doing some job with input data and then call next callback in that series. Look at this simple example (each callback in series increment and print the value):

#include <stdio.h>
//#include <boost/bind.hpp>
//#include <boost/function.hpp>

//typedef boost::function<void (int i)> DataCallback;
typedef void (*DataCallback)(int i);

class A
{
public:
    DataCallback dataCallback;
    void RegisterCallback(DataCallback callback);
    void Callback(int i);
};

void A::RegisterCallback(DataCallback callback)
{
    dataCallback = callback;
}

void A::Callback(int i)
{    
    dataCallback(++i);
    printf("Callback. i = %i", i);
}

int main (void)
{    
    A a1, a2, a3;

    //a1.RegisterCallback(boost::bind(&A::Callback, &a2));
    //a2.RegisterCallback(boost::bind(&A::Callback, &a3));
    a1.RegisterCallback(a2.Callback);
    a2.RegisterCallback(a3.Callback);

    a3.Callback(1);

    return 0;
}

But I have a problem. In C++, you cannot use class member function as callbacks. As I know, solution of this problem is making callback function static. But in this case, I can't use in-class fields. To solve it, I can provide to callback pointer to class (this) and use it in callback. But, in my case, it mean, that I should provide to the lowest callback (a3.Callback) pointers to a2 and a1.

In my real project, I have about 6 callbacks and provide to 6th callbacks pointers to other 5 - is a bad idea, i think.

So, my question is - how to implement this series of callbacks?

As you can see in code, I tried to use boost::function and boost::bind, but MSVS2005 crashes on compile-time (Optimized Compiler has stoped working...) with warning C4180 at mem_fn.hpp@318. What is wrong here and is this the optimal way to solve my problem?

DeniDoman
  • 179
  • 1
  • 3
  • 13
  • 3
    Sounds like an XY problem - perhaps if you describe the ACTUAL problem you are trying to solve, there is a better way to solve the problem (nearly every time I see collbacks in general, I feel that it probably should be a virtual method in a class that derives from a common baseclass). – Mats Petersson Sep 17 '13 at 18:16
  • Seen this one http://stackoverflow.com/questions/2471529/how-to-implement-generic-callbacks-in-c ? – user2672165 Sep 17 '13 at 18:26
  • In the situation you describe just pass your class instance as function parameter, e.g. using a `void*` or baseclass pointer. You can cast this in the callback then. – πάντα ῥεῖ Sep 17 '13 at 18:30

1 Answers1

0

Yes, instead of callback, I'm now register ICallbackable class with Callback() method. Thank you for help.

#include <stdio.h>

class ICallbackable
{
public:
    virtual void Callback(int i) = 0;
};

class A : public ICallbackable
{
public:
    ICallbackable* dataCallback;
    void RegisterCallback(ICallbackable* callback);
    void Callback(int i);
};

void A::RegisterCallback(ICallbackable* callback)
{
    dataCallback = callback;
}

void A::Callback(int i)
{
    printf("Callback. i = %i\n", i);

    if (dataCallback)
    {
        dataCallback->Callback(++i);
    }    
}

int main (void)
{    
    A a1, a2, a3;

    a1.RegisterCallback(NULL);
    a2.RegisterCallback(&a1);
    a3.RegisterCallback(&a2);

    a3.Callback(1);

    return 0;
}
DeniDoman
  • 179
  • 1
  • 3
  • 13