#include <iostream>
using namespace std;
class Foo{
public:
void bar(){
cout << "Foo called\n";
}
};
class Foo2{
public:
void bar2(){
cout << "Foo2 called\n";
}
};
class Function{
public:
virtual void call()=0;
};
template<typename T>
class TemplatedFunction : public Function{
public:
void (T::*m_fkt)();
T* m_obj;
TemplatedFunction(T* obj, void (T::*fkt)()):m_fkt(fkt),m_obj(obj){}
void call(){
(m_obj->*m_fkt)();
}
};
class EventHandler{
public:
Function* m_func=nullptr;
template<class T>
void SetCallbackFunction(T* obj, void (T::*mem_fkt)()){
if(m_func != nullptr)
delete m_func;
m_func = new TemplatedFunction<T>(obj,mem_fkt);
}
void TestCallback(){
if(m_func != nullptr)
m_func->call();
}
~EventHandler(){
if(m_func != nullptr)
delete m_func;
}
};
int main() {
EventHandler eh;
Foo foo;
Foo2 foo2;
eh.SetCallbackFunction(&foo, &Foo::bar);
eh.TestCallback();
eh.SetCallbackFunction(&foo2, &Foo2::bar2);
eh.TestCallback();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY2xhc3MgRm9vewoJcHVibGljOgoJdm9pZCBiYXIoKXsKCQljb3V0IDw8ICJGb28gY2FsbGVkXG4iOwoJfQp9OwoKCmNsYXNzIEZvbzJ7CglwdWJsaWM6Cgl2b2lkIGJhcjIoKXsKCQljb3V0IDw8ICJGb28yIGNhbGxlZFxuIjsKCX0KfTsKCmNsYXNzIEZ1bmN0aW9uewoJcHVibGljOgogICAgdmlydHVhbCB2b2lkIGNhbGwoKT0wOwp9OwoKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CmNsYXNzIFRlbXBsYXRlZEZ1bmN0aW9uIDogcHVibGljIEZ1bmN0aW9uewoJcHVibGljOgoJdm9pZCAoVDo6Km1fZmt0KSgpOwoJVCogbV9vYmo7CgogICAgVGVtcGxhdGVkRnVuY3Rpb24oVCogb2JqLCB2b2lkIChUOjoqZmt0KSgpKTptX2ZrdChma3QpLG1fb2JqKG9iail7fQoKICAgIHZvaWQgY2FsbCgpewogICAgICAobV9vYmotPiptX2ZrdCkoKTsKICAgIH0KfTsKCmNsYXNzIEV2ZW50SGFuZGxlcnsKCXB1YmxpYzoKCUZ1bmN0aW9uKiBtX2Z1bmM9bnVsbHB0cjsKCQoJdGVtcGxhdGU8Y2xhc3MgVD4gCgl2b2lkIFNldENhbGxiYWNrRnVuY3Rpb24oVCogb2JqLCB2b2lkIChUOjoqbWVtX2ZrdCkoKSl7CgkJaWYobV9mdW5jICE9IG51bGxwdHIpCgkJCWRlbGV0ZSBtX2Z1bmM7CgkJbV9mdW5jID0gbmV3IFRlbXBsYXRlZEZ1bmN0aW9uPFQ+KG9iaixtZW1fZmt0KTsKCX0KCQoJdm9pZCBUZXN0Q2FsbGJhY2soKXsKCQlpZihtX2Z1bmMgIT0gbnVsbHB0cikKCQkJbV9mdW5jLT5jYWxsKCk7Cgl9CgkKCX5FdmVudEhhbmRsZXIoKXsKCQlpZihtX2Z1bmMgIT0gbnVsbHB0cikKCQkJZGVsZXRlIG1fZnVuYzsKCX0KfTsKCmludCBtYWluKCkgewoJRXZlbnRIYW5kbGVyIGVoOwoJRm9vIGZvbzsKCUZvbzIgZm9vMjsKCWVoLlNldENhbGxiYWNrRnVuY3Rpb24oJmZvbywgJkZvbzo6YmFyKTsKCWVoLlRlc3RDYWxsYmFjaygpOwoJZWguU2V0Q2FsbGJhY2tGdW5jdGlvbigmZm9vMiwgJkZvbzI6OmJhcjIpOwoJZWguVGVzdENhbGxiYWNrKCk7CglyZXR1cm4gMDsKfQ==