I want to create some callback function to a class. The callback should be not static to have access to the private member variables. For better understanding I made a short example for developing this feature. The problem I have is that the function pointer works for a no class function but not for a private member function.
The function pointer address itself is correct, I verified using printf("%p", cb)
main.cpp
#include <cstdlib>
#include <cstdio>
typedef void f_t (int);
class First {
public:
First(void(cb)(int type)) { mFunc = cb; }
void start(int type) { (mFunc)(type); }
private:
f_t* mFunc;
};
class Second {
public:
Second() {};
void start() {
//First *my = new First((void(*)(int))&Second::onEvt);
First *my = new First(reinterpret_cast<f_t*>(&Second::onEvt));
my->start(123);
}
private:
void onEvt(int type) {
printf("onEvt type: %d\n", type);
}
};
void onEvt2(int type) {
printf("onEvt2 type: %d\n", type);
}
int main() {
First *my = new First((void(*)(int))&onEvt2);
my->start(456);
Second *sec = new Second();
sec->start();
return 0;
}
The result is:
onEvt2 type: 456
onEvt type: 0
I tried different ways of casting but nothing worked for me. I'm not sure if I'm casting on the correct class maybe I have to cast on First
class
Is it possible at all to have such a feature?
This feature should be nearly the same as you can find as wxCommandEventHandler
in the wxWidgets
library.
Thank you for your help.
EDIT - SOLVED
The first answer in the linked dupplicate was the solution. Here is my working example:
#include <cstdlib>
#include <cstdio>
#include <functional>
using namespace std::placeholders; // for `_1`
class First {
public:
First(std::function<void(int)> cb) { mFunc = cb; }
void start(int type) { (mFunc)(type); }
private:
std::function<void(int)> mFunc;
};
class Second {
public:
Second() {};
void start() {
First *my = new First(std::bind(&Second::onEvt, this, _1));
my->start(123);
my->start(456);
}
private:
void onEvt(int type) {
printf("onEvt type: %d\n", type);
}
};
void onEvt2(int type) {
printf("onEvt2 type: %d\n", type);
}
int main() {
First *my = new First(onEvt2);
my->start(789);
Second *sec = new Second();
sec->start();
return 0;
}