Is there some library that allows me to easily and conveniently create Object-Oriented callbacks in c++?
the language Eiffel for example has the concept of "agents" which more or less work like this:
class Foo{
public:
Bar* bar;
Foo(){
bar = new Bar();
bar->publisher.extend(agent say(?,"Hi from Foo!", ?));
bar->invokeCallback();
}
say(string strA, string strB, int number){
print(strA + " " + strB + " " + number.out);
}
}
class Bar{
public:
ActionSequence<string, int> publisher;
Bar(){}
invokeCallback(){
publisher.call("Hi from Bar!", 3);
}
}
output will be: Hi from Bar! 3 Hi from Foo!
So - the agent allows to to capsule a memberfunction into an object, give it along some predefined calling parameters (Hi from Foo), specify the open parameters (?), and pass it to some other object which can then invoke it later.
Since c++ doesn't allow to create function pointers on non-static member functions, it seems not that trivial to implement something as easy to use in c++. i found some articles with google on object oriented callbacks in c++, however, actually i'm looking for some library or header files i simply can import which allow me to use some similarily elegant syntax.
Anyone has some tips for me?
Thanks!
Joining the idea of functors - use std::tr1::function and boost::bind to build the arguments into it before registering it.
There are many possibilities in C++, the issue generally being one of syntax.
boost::bind
for an even more... interesting... syntax (*)()
operator, for examplevoid Functor::operator()(int a) const;
, because it's an object it has state and may derive from a common interfacestd::function
+ the lambda functions are truly awesome when it comes to expressiveness.I would appreciate a review on lambda syntax ;)
Of course,
func
is only viable whilefoo
is viable (scope issue), you could copyfoo
using[=foo]
to indicate pass by value instead of pass by reference.(*) Mandatory Tutorial on Function Pointers
There are various libraries that let you do that. Check out boost::function.
Or try your own simple implementation:
Usage:
C++ allows function pointers on member objects.
See here for more details.
You can also use boost.signals or boost.signals2 (depanding if your program is multithreaded or not).
People typically use one of several patterns:
Inheritance. That is, you define an abstract class which contains the callback. Then you take a pointer/reference to it. That means that anyone can inherit and provide this callback.
Inheritance again. That is, your root class is abstract, and the user inherits from it and defines the callbacks, rather than having a concrete class and dedicated callback objects.
Even more inheritance- static. This way, you can use templates to change the behaviour of an object. It's similar to the second option but works at compile time instead of at run time, which can yield various benefits and downsides, depending on the context.
You can take and use member function pointers or regular function pointers
There are function objects- they overload operator(). You will want to use or write a functional wrapper- currently provided in std::/boost:: function, but I'll also demonstrate a simple one here. It's similar to the first concept, but hides the implementation and accepts a vast array of other solutions. I personally normally use this as my callback method of choice.
The right solution mainly depends on the context. If you need to expose a C-style API then function pointers is the only way to go (remember void* for user arguments). If you need to vary at runtime (for example, exposing code in a precompiled library) then static inheritance can't be used here.
Just a quick note: I hand whipped up that code, so it won't be perfect (like access modifiers for functions, etc) and may have a couple of bugs in. It's an example.
The most OO way to use Callbacks in C++ is to call a function of an interface and then pass an implementation of that interface.