Click to See Complete Forum and Search --> : How to make a callback function without template?


StupidBug
June 30th, 1999, 08:22 PM
I need a class like

class EventHandler {
public:
EventHandler(){}
void setHandler(...); //accept a pointer to member function like
// &ClassA::onClick
int invoke(); //excute the member function
}



How to make such a class without template?(because a need a container to keep all the EventHandlers.) Please help me...

as_prabhu
July 1st, 1999, 04:45 AM
In the 'Invoke' method, you have to freeze the signature of the callback anyway ( unless you have different notifications to be sent for different cases.) Anyway, the best way to handle this is to have an abstract base class as a callback as shown below.


class CCallback
{
virtual void OnInvoke()=0;
};




So in the SetHandler method you can pass a ref to this class.


class EventHandler
{
public:
EventHandler(){}
void setHandler(CCallback* pCb);
int invoke();
};






In the implementation of 'Invoke', you can blindly invoke CCallback::OnInvoke()

Since CCallback is abstract, anybody implementing the callback needs to override the 'OnInvoke' method.

StupidBug
July 2nd, 1999, 07:41 AM
Hi,Thank you for your help.
That's a good idea,but it seems a little complex to use.I love the eventHandler in VJ6.

class Control{
public:
Control();
virtual int onClick();
}
class Edit:public Control{
public:
Edit();
virtual init(){
//elegant,isn't it? How to implement?
addEvenHandler(new EventHandler(&Edit::onClick));
addEvenHandler(new EventHandler(&Edit::onKeyPress));
}
virtual int onclick();
virtual int onKeyPress();
}

I tried this way:

#include <iostream>
using namespace std;

class Control{
public:
Control(){}
virtual int onClick(){
cout<<"Control: Click"<<endl;
return 1;
}
};

class Edit:public Control{
public:
Edit(){}
virtual int onKeyPress(){
cout<<"Control: KeyPress"<<endl;
return 1;
}
};

class EventHandler{
private:
Control* m_pObject;
int (Control::*m_pMemFun)();
public:
template <class Obj,class PtrMemFun>
EventHandler(Obj* o,PtrMemFun pf){
m_pObject=o;
m_pMemFun=(PtrMemFun)pf;
}
int invoke(){
return (m_pObject->*m_pMemFun)();
}
};

int main(){
Edit* edit1=new Edit();
//ok
EventHandler* e=new EventHandler(edit1,&Edit::onClick);
e->invoke();
//error:cannot convert from 'int(__thiscallEdit::*) void)' to 'int (__thiscall Control::*)(void)'
//Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
//see reference to function template instantiation '__thiscall EventHandler::EventHandler(class Edit *,int (__thiscall Edit::*)(void))' being compiled
EventHandler* e2=new EventHandler(edit1,&Edit::onKeyPress);
e2->invoke();
return 0;
}



The problem is: How to convert one kind of member function pointer to other kind of member function pointer?