Question

Suppose I have some code like this:

class Visitor {
   public:
      Visitor(callBackFunction) {}
      void visit() {
          //do something useful
          invokeCallback();
      }
}

class ClassThatCanBeVisited {
    Visitor &visitor;

    public:
       ClassThatCanBeVisited(Visitor &_visitor) : visitor(_visitor){}
       void someUsefulMethod() {
          int data= 42;
          visitor.visit(data);
       }
};


void callBackFunction() {
    //do something useful in the context of the Main file
}
int main() {
     Visitor visitor;
     ClassThatCanBeVisited foo(visitor);
     foo.someUsefulMethod();
}

I need to create a simple callback that will be called whenever the Visitor::visit() is called. I know that I probably should put the code of the callback inside my Visitor, but it is in a different context, so I would like to pass the callBackFunction() to the Visitor so he could invoke my callback function.

I looked for things on the web and saw boost::function, but c++ already has the basic functors.

Which one should I use for better clarity of the code? The callback is going to be a simple void() function, but it might grow, you never know the future :)

What is the recommended way to do this?

Was it helpful?

Solution

You can use callback interface and its hierarchy if you don't want to use boost::function.

class VisitorCallback
{
public:
    virtual void handle( const Visitor& ) = 0;
};

If you have or can use boost::function - use it, it is a good way to get rid of all those callback classes.

Edit:
@edisongustavo:

boost::function and boost::bind won't probably make your code more readable. But it will give you an opportunity to pass free functions ( I mean functions out of class and static class functions ) as callback as well as existing functions of any class.

With boost functions you can pass functions with for example 2 parameters as callback which expect only one parameter.

typedef boost::function< void ( int ) > IntExpectingCallback;

void TwoIntFunction( int, int );
{
}
...
IntExpectingCallback callback = boost::bind( TwoIntFunction, 5, _1 );

But again, this won't make your code more readable unless all your team knows and favor boost.

OTHER TIPS

Yes boost::function would do this well. That's a very common usage of it. You will need to use boost::bind to bind the instance to the member function.

 func = boost::bind( &MyClass::CallbackFunc, this);

Would be how you would do that from within the class.

Be sure the "this" doesn't dissapear or your boost function will crash in the middle of some boost header somewhere.

The above answers are great, but I'd just like to point out something you mentioned in your question, which is still relevant to your choice between C++ callback objects (in Mykola's answer) and boost.

"the callback is going to be a simple void() function, but it might grow, you never know the future :)"

This is probably the worst reason to extra, unnecessary functionality - that is "just in case you need it". If you don't know - then don't do more than is necessary, chances are your guess will be wrong anyway, especially by the time you need it.

On the other hand, if you do know that it is extremely likely you will need the functionality very soon, then it might be worth adding it.

Again to re-iterate what Mykola said - if you already have boost in your project and your team likes it, then use that, but otherwise it may be overkill.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top