I'm trying to give a method as a callback of another method just like that:
Actions actions;
Button button;
int main()
{
actions = Actions();
button = Button();
button.onClick(actions.doSmthg);
return 0;
}
Here is my Actions
:
class Actions {
public:
Actions();
void doSmthg();
};
and here is the Button
with my attempt of implementing a callback pattern:
class Button {
public:
Button() {};
void onClick(void (*callbackPtr)());
};
Sadly I got the following error:
error: invalid use of non-static member function ‘void Actions::doSmthg()’
I've check multiple examples that suggest to use std::bind
when dealing with callbacks but I'm really not sure how to make it work.
Any idea to implement such a pattern in C ?
Here is a live sandbox https://onlinegdb.com/nL3SIUOaI.
CodePudding user response:
Method 1
You can make use of std::bind
and std::function
as shown below:
#include <iostream>
#include <functional>
class Actions {
public:
Actions(){}
void doSmthg(){
std::cout<<"do something called"<<std::endl;
}
};
class Button {
public:
Button() {};
void setFunc(std::function<void ()> eventFunction) { fn = eventFunction; }
void onClick(){
std::cout<<"button clicked"<<std::endl;
//call the function on the passed object
fn();
}
private:
std::function<void ()> fn;
};
int main()
{
Actions action;
Button button;
button.setFunc(std::bind(&Actions::doSmthg, action));
button.onClick();
return 0;
}
The output of the above program can be seen here:
button clicked
do something called
Method 2
Here we make the onClick
member function to be a member function template.
#include <iostream>
class Actions {
public:
Actions(){}
void doSmthg(){
std::cout<<"do something called"<<std::endl;
}
};
class Button {
public:
Button() {};
template<typename T>
void onClick(void (T::*callbackPtr)(), T obj){
std::cout<<"button clicked"<<std::endl;
//call the function on the passed object
(obj.*callbackPtr)();
}
};
int main()
{
Actions action;
Button button;;
button.onClick<Actions>(&Actions::doSmthg, action);
return 0;
}
The output of the above program can be seen here:
button clicked
do something called