How to pass a method as callback to another class? - c++

I have a question regarding callbacks using tr1::function. I've defined the following:
class SomeClass {
public:
typedef std::tr1::function<void(unsigned char*, int)> Callback;
void registerCallback(Callback);
private:
Callback callback;
}
I've defined another class:
class SomeOtherClass {
void myCallback(unsigned char*, int);
}
Now I want to register my function 'myCallback' as callback at class 'SomeClass'using the method 'registerCallback'. However, it is not working. I've had a look on the boost documentation on the function and it seems legit to use (member) methods of a class for callbacks. Am I wrong?
Thanks in advance!

Member functions have an implicit first parameter, a this pointer so as to know which object to call the function on. Normally, it's hidden from you, but to bind a member function to std::function, you need to explicitly provide the class type in template parameter.
#include <functional>
#include <iostream>
struct Callback_t {
void myCallback(int)
{
std::cout << "You called me?";
}
};
class SomeClass {
public:
SomeClass() : callback() { }
typedef std::function<void(Callback_t*, int)> Callback;
// ^^^^^^^^^^^
void registerCallback(const Callback& c)
{
callback = c;
}
void callOn(Callback_t* p)
{
callback(p, 42);
}
private:
Callback callback;
};
int main()
{
SomeClass sc;
sc.registerCallback(&Callback_t::myCallback);
Callback_t cb; // we need an instance of Callback_t to call a member on
sc.callOn(&cb);
}
Output: You called me?;

Why all this complicated mumbo-jumbo?
Why not create a class as thus (for example)
Class MouseOverEventCallBack
{
public:
virtual void RunMouseOverCallback() = 0;
};
Then just create classes that inherit this class (and redefine the method RunMouseOverCallback)
Then Register function just needs to be
void registerCallback(MouseOverEventCallBack *callbackObject); // possible could use a reference
The register method will just call the method and the object will have all that it needs.
Seems a bit simpler. Let the compiler do the work with pointers to functions etc.

the function void (*)(unsigned char*, int) is a free function, which is a different type from void (SomeOtherClass::*)(unsigned char*, int), thus the error. You need an object to call the latter, while the former is a free function.
Look at the possible solutions listed in the Boost documentation
Another possibility is that your SomeOtherClass::myCallback is private, so you do not have access to it.

Use templates:
template <class T>
class B
{
public:
typedef void (T::*TCallBackFunction)(void);
void SetCallBack(T* pCallBackClass, TCallBackFunction pCallBackFunction)
{
if(pCallBackFunction && pCallBackClass)
{
m_pCallBackFunction = pCallBackFunction;
m_pCallBackClass = pCallBackClass;
}
}
void StartCallBackFunction()
{
(pCallBackClass->(*m_pCallBackFunction))();
}
private:
TCallBackFunction m_pCallBackFunction;
T* m_pCallBackClass;
};
Such like this. And use it:
...
B<MyClass> b;
b.SetCallBack(&b, &MyClass::MyFunction);
...

Related

Provide a pointer to member function to be invoked by the target class without functional

I'm reading a lot of questions (and answers) about function pointers, functors and callbacks but I still have a confusion about which is the right tool for me.
Some of them cannot apply to my scenario because it seems my compiler avr-gcc v5.4.0 does not have C++ standard library (i.e. std::function is not available).
This is my base class:
class Debouncer
{
public:
typedef uint8_t (Debouncer::*debouncer_raw_t) (void);
Debouncer() {}
void setRawFunction(Debouncer::debouncer_raw_t callback) { _raw = callback; }
private:
debouncer_raw_t _raw;
void anotherFunction()
{
uint8_t value = _raw();
// do something
}
}
In my other classes I have:
class Inputs
{
public:
Inputs()
{
_deb.setRawFunction(myRaw);
}
private:
Debouncer _deb;
uint8_t myRaw()
{
return something;
}
}
Of course this won't compile because myRaw is not static.
Anyway, I'm going to try to avoid this because it would break the existing code.
If I'm not wrong, a lot of questions seem to ask the other way around.
Instead I just want to pass the pointer of my member function to my Debouncer class, so it can call _raw() when it needs to.
Here I found this advise to avoid std:: library:
#define CALL_MEMBER_FN(object, ptrToMember) ((object).*(ptrToMember))
void userCode(Fred& fred, FredMemFn p) // Use a typedef for pointer-to-member types
{
int ans = CALL_MEMBER_FN(fred,p)('x', 3.14);
// Would normally be: int ans = (fred.*p)('x', 3.14);
// ...
}
But it seems the other way around. Here the class Fred is my Debouncer.
I don't want to call the Debouncer member, but member of the caller class (i.e. Input::myRaw()).
Would you please help me to understand which is the right tool to achieve such a simple task?
Making a member function virtual is a relatively low-overhead way to have a single pointer (to an object) refer to both the object's data and the correct member function.
class InputsBase
{
// All classes that implement myRaw() should inherit from this class
public:
virtual uint8_t myRaw() = 0;
};
class Inputs : public InputsBase
{
public:
Inputs()
{
_deb.setRawFunction(this);
}
private:
Debouncer _deb;
virtual uint8_t myRaw()
{
return something;
}
}
Your Debouncer can then simply store a pointer to the object in question.
class Debouncer
{
public:
typedef InputsBase* debouncer_raw_t;
Debouncer() {}
void setRawFunction(debouncer_raw_t callback) { _raw = callback; }
private:
debouncer_raw_t _raw;
void anotherFunction()
{
uint8_t value = _raw->myRaw();
// do something
}
}
If you know (or require) each of the classes using Debouncer have a public myRaw() function (or better operator(), or actually anything else), the problem is simpler:
template <typename T>
class Debouncer
{
public:
Debouncer (T* t): _t(t) {}
void anotherFunction()
{
uint8_t value = _t->myRaw();
std::cout << static_cast<int>(value);
}
private:
T* _t;
};
class Inputs
{
public:
Inputs() : _deb(this)
{
// beware, if Debouncer uses its parameter in constructor (like call a method),
// you cannot use initializer list
}
uint8_t myRaw()
{
return 13;
}
void foo()
{
_deb.anotherFunction();
}
private:
Debouncer<Inputs> _deb;
};
int main()
{
Inputs i;
i.foo();
}
This would be preferred solution in C++. See for example standard library <algorithm> - any function taking a predicate or some other callable expects to call it with operator() rathen than having to deal with pointers-to-member-function.
If you don't know what function should be called and you really cannot impose any requirement on the classes, you need to store both a pointer (or reference) to the class and a pointer to the member function. Note that you cannot connect pointers to member functions of different classes, so we need templates once again:
template <typename T, typename Func>
class Debouncer
{
public:
Debouncer (T* t, Func f): _t(t), _f(f) {}
void anotherFunction()
{
uint8_t value = (_t->*_f)(); //I get it now why isocpp asks to use macro here, the syntax is horrible
std::cout << static_cast<int>(value);
}
private:
T* _t;
Func _f;
};
class Inputs
{
public:
Inputs() : _deb(this, &Inputs::myRaw)
{
// beware, if Debouncer uses its parameter in constructor (like call a method),
// you cannot use initializer list
}
uint8_t myRaw()
{
return 13;
}
void foo()
{
_deb.anotherFunction();
}
private:
Debouncer<Inputs, decltype(&Inputs::myRaw)> _deb; //decltype is C++11, you could also declare type like you did in your question
};
int main()
{
Inputs i;
i.foo();
}

Can i pass a function from a class to a constructor of another class and store it there to call later? C++

So basically I'm making buttons in a game, and the buttons are a called Button.
The class i want the function from to store is called SoccerLevelsClass. I've tried looking into function pointers, but I'm not sure what's going on though i think it's the correct thing to do.
I want to save the function of SoccerLevelsClass as a member of Button.
Would i do something like this?
//MenuButton.h
#ifndef MenuButton
#define MenuButton
....
class Button
{
public:
Button(void(*SoccerLevelsClass::func)());
void (*SoccerLevelsClass::function)();
....
}
#endif
//MenuButton.cpp
#include <MenuButton.h>
Button::Button(void(*SoccerLevelsClass::func)())
{
function=func; //something like this
}
I know the code is probably way off, but I'd like to know if anybody has any suggestions.
All i really want to know is if it's possible.
Yes, this can be done - either with function pointers like in your example, or with lambdas if you can use C++11.
However, since you want to call a bound function of another class, you would need to pass/store pointer to an instance of that class as well to do that, unless the function is static.
In C++11, this is trivial:
std::function<void(void)> _f;
void apply() {
_f();
}
Bar(void (Foo::* f)()) {
_f = std::bind(f, Foo());
}
In C++03, this is a little tricky. Note in both versions I construct a temporary to call the member function, but I'm not sure whether it is necessary to store an instance of the class.
#include <iostream>
#include <functional>
struct Foo
{
Foo() { }
void stuff() {
std::cout << "hi\n";
}
};
struct Bar
{
void (Foo::* _f)();
void apply() {
(Foo().*_f)();
}
Bar(void (Foo::* f)()) {
_f = f;
}
};
int main()
{
Bar bar(&Foo::stuff);
bar.apply();
}
For what you are trying to do I would use the observer pattern:
class IFootballObserver
{
public:
virtual void OnBallKicked() = 0;
virtual ~IFootballObserver() {}
};
class Fooball
{
public:
Fooball(IFootballObserver& obs)
: mObs(obs)
{
// Call the observer interface at any time like so:
mObs.OnBallKicked();
}
private:
IFootballObserver& mObs;
};
class Button : public IFootballObserver
{
public:
// Football could be passed in/owned by something else
Button() : mFootball(*this) { }
void DoSomething()
{
// Called when foot ball is kicked
}
private:
virtual void OnBallKicked()
{
DoSomething();
}
Fooball mFootball;
};
I find this easier than using function pointers/std::function. Plus you could have a vector of observers and notify many objects of events.

Passing function name as parameter of Another function in C++ class

I have two classes A and B. I want to pass a function name in class A as parameter of function in Class B. I tried with below sample, Is it correct way.
class A
{
public:
B m_b;
void MyFun()
{
// do something
}
void Test()
{
m_b.Process( MyFun );
}
}
class B
{
public:
void Process( void (*f)() )
{
(*f)();
}
}
thanks in advance
Since MyFun is a member function of class A, you need a pointer-to-member instead of a regular function pointer, and you also need an instance of class A to invoke the function on:
class B
{
public:
void Process(A *obj, void (A::*f)() )
{
(obj->*f)();
}
}
Actually, if MyFun is not a static member of your class, it has a hidden argument that is of type A*, so this is implemented like: m_a.MyFun(...) =~ MyFunImpl(&m_a, ...).
So, What you want is probably have a static function MyFun (you can't use this inside it), and inside B::Process call f().
If you need to pass this, refer to casablanca's answer (pointers to member functions).
Otherwise, if you want to pass an argument, you can lookup std::bind or lambda functions (C++0x), or boost::bind prior to that.
Follow the advice here: http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.4, you'll end up with this:
class A;
typedef void (A::*MemFun)();
class B
{
public:
void Process(A& a, MemFun mf)
{
(a.*mf)();
}
};
class A
{
public:
B m_b;
void MyFun()
{
// do something
}
void Test()
{
MemFun p = &A::MyFun;
A a;
m_b.Process(a, p);
}
};

Object-Oriented Callbacks for C++?

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!
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.
#include <iostream>
class Interface
{
public:
virtual void callback() = 0;
};
class Impl : public Interface
{
public:
virtual void callback() { std::cout << "Hi from Impl\n"; }
};
class User
{
public:
User(Interface& newCallback) : myCallback(newCallback) { }
void DoSomething() { myCallback.callback(); }
private:
Interface& myCallback;
};
int main()
{
Impl cb;
User user(cb);
user.DoSomething();
}
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.
class Foo {
virtual void MyCallback(...) = 0;
virtual ~Foo();
};
class Base {
std::auto_ptr<Foo> ptr;
void something(...) {
ptr->MyCallback(...);
}
Base& SetCallback(Foo* newfoo) { ptr = newfoo; return *this; }
Foo* GetCallback() { return ptr; }
};
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.
class Foo {
virtual void MyCallback(...) = 0;
...
};
class RealFoo : Foo {
virtual void MyCallback(...) { ... }
};
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.
template<typename T> class Foo {
void MyCallback(...) {
T::MyCallback(...);
}
};
class RealFoo : Foo<RealFoo> {
void MyCallback(...) {
...
}
};
You can take and use member function pointers or regular function pointers
class Foo {
void (*callback)(...);
void something(...) { callback(...); }
Foo& SetCallback( void(*newcallback)(...) ) { callback = newcallback; return *this; }
void (*)(...) GetCallback() { return callback; }
};
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.
class Foo {
virtual ... Call(...) = 0;
virtual ~Foo();
};
class Base {
std::auto_ptr<Foo> callback;
template<typename T> Base& SetCallback(T t) {
struct NewFoo : Foo {
T t;
NewFoo(T newt) : t(newt) {}
... Call(...) { return t(...); }
};
callback = new NewFoo<T>(t);
return this;
}
Foo* GetCallback() { return callback; }
void dosomething() { callback->Call(...); }
};
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.
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).
There are various libraries that let you do that. Check out boost::function.
Or try your own simple implementation:
template <typename ClassType, typename Result>
class Functor
{
typedef typename Result (ClassType::*FunctionType)();
ClassType* obj;
FunctionType fn;
public:
Functor(ClassType& object, FunctionType method): obj(&object), fn(method) {}
Result Invoke()
{
return (*obj.*fn)();
}
Result operator()()
{
return Invoke();
}
};
Usage:
class A
{
int value;
public:
A(int v): value(v) {}
int getValue() { return value; }
};
int main()
{
A a(2);
Functor<A, int> fn(a, &A::getValue);
cout << fn();
}
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.
You can use pointer to functions when you don't require state, but the syntax is really horrid. This can be combined with boost::bind for an even more... interesting... syntax (*)
I correct your false assumption, it is indeed feasible to have pointer to a member function, the syntax is just so awkward you'll run away (*)
You can use Functor objects, basically a Functor is an object which overloads the () operator, for example void Functor::operator()(int a) const;, because it's an object it has state and may derive from a common interface
You can simply create your own hierarchy, with a nicer name for the callback function if you don't want to go the operator overloading road
Finally, you can take advantage of C++0x facilities: std::function + the lambda functions are truly awesome when it comes to expressiveness.
I would appreciate a review on lambda syntax ;)
Foo foo;
std::function<void(std::string const&,int)> func =
[&foo](std::string const& s, int i) {
return foo.say(s,"Hi from Foo",i);
};
func("Hi from Bar", 2);
func("Hi from FooBar", 3);
Of course, func is only viable while foo is viable (scope issue), you could copy foo using [=foo] to indicate pass by value instead of pass by reference.
(*) Mandatory Tutorial on Function Pointers

Member Function Pointer with base class argument accepting derived class argument

So I'm working on this event management class. I'm storing a list of pointers to member functions of the signature void (Event*) where Event is just a struct that stores some random data at the moment.
typedef boost::function<void(Event*)> Callback;
typedef vector<Callback> CallbackList;
class EventManager
{
public:
template<typename T>
void RegisterEventHandler(const std::string& type, void (T::*handler)(Event*), T* obj)
{
mCallbackList[type].push_back(boost::bind(handler, obj, _1));
}
void DispatchEvent(const std::string& type, Event* evt)
{
for(CallbackList::iterator it = mCallbackList[type].begin(); it != mCallbackList[type].end(); ++it)
{
Callback callback = (*it);
callback(evt);
}
}
private:
hash_map<std::string, CallbackList> mCallbackList;
};
I'm wondering, if it's possible for me to derive different versions of Event, and pass pointers to those member functions into this class? Currently I'm trying this.
class MouseEvent : public Event
{
public:
int testMouseData1;
int testMouseData2;
int testMouseData3;
};
class HelloWorld
{
public:
void Display(MouseEvent* evt)
{
cout << "Hello, world!" << endl;
}
};
int main(void)
{
MouseEvent* evt = new MouseEvent();
HelloWorld* world = new HelloWorld();
eventManager->RegisterEventHandler("testType", &HelloWorld::Display, world);
return 0;
}
This gives me the following error in XCode.
error: no matching function for call to 'EventManager::RegisterEventHandler(const char [9], void (HelloWorld::*)(MouseEvent*), HelloWorld*&)'
Do you know how I can safely pass in a pointer that's expecting a derived class in its function signature? Thanks.
So I found a solution that seems to be working for me, but I'm not sure if it's entirely safe to do. I changed the RegisterEventHandler method to cast all of the function pointers that I send in to the same type...
template<typename T1, typename T2>
void RegisterEventHandler(const String& type, T1 handler, T2* obj)
{
void (T2::*evtHandler)(Event*) = (void (T2::*)(Event*)) (handler);
mCallbackList[type].push_back(boost::bind(evtHandler, obj, _1));
}
now it all seems to just work as I originally intended. But I'm pretty new to all this so I'm not entirely sure if this is a safe thing to do. Any thoughts? Thanks
If your prototype expects "Event" type then you need to make sure the void Display(MouseEvent* evt) function is accepting the "Event" type. So change it to void Display(Event *evt) Then inside the call you can typecast it back to a MouseEvent, assuming that the caller passed an actual MouseEvent, referenced as an "Event".
Secondly, I believe you may have some other issues with the way you are calling RegisterEventHandler since it is in a template but you are not specifying the template type.