Introduction This article explains about Callbacks and implmentation of it using below 3 different methods: Static Functions Non-Static or Member Functions Functor or Function Objects. Background About CallBack It is an executable code, that is passed as an argument to other independent block of code or function to perform the required task. Here, it separates the callee from caller. Caller only needs to know the prototype of that function that would be used as a callback. So callbacks provide a mechanism where-in independently developed objects can be connected together, to meet the requirement. It's Usage 1. Mostly, these callbacks are written in a common/generic library, so the applications can make use of them on needed basis - like "compare function" that acts as a callback and can be used in searching, sorting objects in a list or container. 2. If you want to terminate the application because of some trap, then to make sure of things that needs to be taken care before terminating the application, for that the application would register itself to a common callback utility that may be called as "cleanup". 3. Callbacks are also used in event handling in Finite State Machines or FSM. Wherein callback functions are used to perform set of things, on receiving an event and before changing to next state. Lets take one problem/requirement to illustrate the implementation of callbacks using the above mentioned 3 different methods The requirement is to find the Employee with given empId in the container. So the function for finding the Employee in the container uses the callback function or functor, for comparing the given empId with the empId of all the employee objects stored in the container and send the appropriate result. Classes involed are: class CallBackEmpInterface - Is a Base class contains empId_m. class CallBackEmployee - Is a Employee class derives from CallBackEmpInterface class class CallBackEmpContainer - Contains objects of class CallBackEmplyee Implementation of Callback using Static or Member function of class object Here Static function acts as a callback, whose function pointer is sent as a argument to the application which is going to make use of that specific callback later in it's computation. The code Code: #include<iostream.h> class CallBackEmpInterface { unsigned int empId_m; public: CallBackEmpInterface() { cout<<"Ctor ::CallBackEmpInterface::default\n"; } CallBackEmpInterface(unsigned int empId):empId_m(empId) { cout<<"Ctor ::CallBackEmpInterface\n"; } unsigned int empId() { return (empId_m); } static bool compareEmpId(CallBackEmpInterface* obj1, CallBackEmpInterface* obj2) { cout<<"\n\nCalling static function - CallBackEmpInterface::compareEmpId \n"; if(obj1->empId() == obj2->empId()) { return(0); //--- } else if(obj1->empId() < obj2->empId()) { return(-1); //--- } else { return(1); //--- } } }; class CallBackEmployee : public CallBackEmpInterface { public: CallBackEmployee(unsigned int empId):CallBackEmpInterface(empId) { cout<<"Ctor ::CallBackEmployee\n"; } }; class CallBackEmpContainer { public: CallBackEmpContainer(): basePtr_mpp(NULL) { basePtr_mpp = new (CallBackEmpInterface *)[2]; } void insert(const CallBackEmpInterface *obj_p) { CallBackEmpInterface *tempObj_p; tempObj_p = (CallBackEmpInterface *)obj_p; if(count !=2) { basePtr_mpp[count] = tempObj_p; ++count; } } void find(CallBackEmpInterface *critObj_p, bool (*compFun_p)(CallBackEmpInterface* obj1, CallBackEmpInterface* obj2)) { unsigned int i; for(i=0; i<2; ++i) { // here calling the calling back function compareEmpId to find the result if(0 == (compFun_p(basePtr_mpp[i], critObj_p))) { cout<<"Found the object with empId as "<<critObj_p->empId()<<"...\n\n" ; return; } } cout<<"The container does not have this empId...\n\n"; } private: CallBackEmpInterface ** basePtr_mpp; static unsigned int count; }; unsigned int CallBackEmpContainer::count = 0; int main() { cout<<"Implementation of Callback Function using Static Function ...\n"; cout<<"----------------------------------------------------------------\n\n"; CallBackEmployee *obj1 = new CallBackEmployee(1); CallBackEmployee *obj2 = new CallBackEmployee(2); CallBackEmpContainer cb; cb.insert(obj1); cb.insert(obj2); //Create the criterian, to find a object with empId as "1" in the container CallBackEmployee *obj3 = new CallBackEmployee(1); //Find the object of type criterian obj3 in the container and send the results cb.find(obj3, CallBackEmpInterface::compareEmpId); delete (obj1); delete (obj2); delete (obj3); return(0); } Output: -------------- Implementation of Callback Function using Static Function ... ---------------------------------------------------------------------- Ctor ::CallBackEmpInterface Ctor ::CallBackEmployee Ctor ::CallBackEmpInterface Ctor ::CallBackEmployee Ctor ::CallBackEmpInterface Ctor ::CallBackEmployee Calling static function - CallBackEmpInterface::compareEmpId Found the object with empId as 1... Here in this example, the static function compateEmpId is a comparision function, acts as a callback, whose function pointer is sent as an argument to find function. Where-as this find function is used by the main function for searching the Employee with specific empId in the container. Implementation of Callback using Non-Static or Member function Since pointer to member or non-static functions of a class object need the this pointer as well, it differs from the signature of the ordinary function pointers. But using the below work around, we can still make a callback to a member function. A. Write a Static function as a Wrapper to a member function (which acts as a callback) providing the below arguments as - void pointer - which can be used to cast to the pointer to the object, whose member function can be invoked as a callback. Required parameters to call back function. B. Call the member function using the cast ed pointer, by sending all the required parameters from this static function. C. Then send the pointer to this Static Function as a argument to the function or application, where-in the callback function can be used in it's computation. The code Code: #include<iostream.h> class CallBackEmpInterface { unsigned int empId_m; public: CallBackEmpInterface() { cout<<"Ctor ::CallBackEmpInterface::default\n"; } CallBackEmpInterface(unsigned int empId):empId_m(empId) { cout<<"Ctor ::CallBackEmpInterface\n"; } unsigned int empId() { return (empId_m); } bool compareEmpId(CallBackEmpInterface* obj1, CallBackEmpInterface* obj2) { cout<<"\n\nCalling member function CallBackEmpInterface::compareEmpId \n"; if(obj1->empId() == obj2->empId()) { return(0); //--- } else if(obj1->empId() < obj2->empId()) { return(-1); //--- } else { return(1); //--- } } static bool wrapperToCompareEmpId(void* thisPtr, CallBackEmpInterface* obj1); }; bool CallBackEmpInterface::wrapperToCompareEmpId(void * thisPtr, CallBackEmpInterface *obj1) { cout<<"\n\nCallBackEmpInterface::wrapperToCompareEmpId\n"; CallBackEmpInterface *myObj = (CallBackEmpInterface *)thisPtr; return (myObj->compareEmpId(myObj, obj1)); } class CallBackEmployee : public CallBackEmpInterface { public: CallBackEmployee(unsigned int empId):CallBackEmpInterface(empId) { cout<<"Ctor ::CallBackEmployee\n"; } }; class CallBackEmpContainer { public: CallBackEmpContainer(): basePtr_mpp(NULL) { basePtr_mpp = new (CallBackEmpInterface *)[2]; } void insert(const CallBackEmpInterface *obj_p) { CallBackEmpInterface *tempObj_p; tempObj_p = (CallBackEmpInterface *)obj_p; if(count !=2) { basePtr_mpp[count] = tempObj_p; ++count; } } void find(CallBackEmpInterface *critObj_p, bool (*wrapperFunc_p)(void *thisPtr, CallBackEmpInterface* obj1)) { unsigned int i; for(i=0; i<2; ++i) { // here calling the calling back function compareEmpId to find the result if(0 == (wrapperFunc_p(critObj_p, basePtr_mpp[i]))) { cout<<"Found the object with empId as "<<critObj_p->empId()<<"...\n\n" ; return; } } cout<<"The container does not have this empId...\n\n"; } private: CallBackEmpInterface ** basePtr_mpp; static unsigned int count; }; unsigned int CallBackEmpContainer::count = 0; int main() { cout<<"Implementation of Callback Function using Non-Static or Member Function ...\n"; cout<<"----------------------------------------------------------------------------\n\n"; CallBackEmployee *obj1 = new CallBackEmployee(1); CallBackEmployee *obj2 = new CallBackEmployee(2); CallBackEmpContainer cb; cb.insert(obj1); cb.insert(obj2); //Create the criterian, to find a object with empId as "1" in the container CallBackEmployee *obj3 = new CallBackEmployee(1); //Find the object of type criterian obj3 in the container and send the results cb.find(obj3, CallBackEmpInterface::wrapperToCompareEmpId); delete (obj1); delete (obj2); delete (obj3); return(0); } Output ------------ Implementation of Callback Function using Non-Static or Member Function ... ------------------------------------------------------------------------------------------ Ctor ::CallBackEmpInterface Ctor ::CallBackEmployee Ctor ::CallBackEmpInterface Ctor ::CallBackEmployee Ctor ::CallBackEmpInterface Ctor ::CallBackEmployee CallBackEmpInterface::wrapperToCompareEmpId Calling member function CallBackEmpInterface::compareEmpId Found the object with empId as 1... Here in this example, compareEmpId is a member function of CallBackEmpInterface class, acts as a callback. This is done by having a static function called wrapperToCompareEmpId in the same class (which takes void pointer and required arguments to the callback function and in turn calls the compareEmpId function in it's implementation) and whose function pointer is sent to the find method and is used in the main function to find Employee with specific empId. Implementation of Callback using Function Object or Functor Functor is an object that acts like a function. Functor object overloads the parenthesis operator i.e. operator( ) that can return anything and can accept any number of parameters. For Example: Here is a Functor that overloads operator ( ) to print a given string. Code: class MyFunctor { void operator() (const string& str) const { cout<<str<<endl; } } The same way, we can overload operator() for comparison function and that can be called as a callback from an application. The code Code: #include<iostream.h> class CallBackEmpInterface { unsigned int empId_m; public: CallBackEmpInterface() { cout<<"Ctor ::CallBackEmpInterface::default\n"; } CallBackEmpInterface(unsigned int empId):empId_m(empId) { cout<<"Ctor ::CallBackEmpInterface\n"; } unsigned int empId() { return (empId_m); } virtual bool callback(CallBackEmpInterface* obj1, CallBackEmpInterface* obj2) { cout<<"CallBackEmpInterface::callBack \n"; } }; class CallBackEmployee : public CallBackEmpInterface { public: CallBackEmployee(unsigned int empId):CallBackEmpInterface(empId) { cout<<"Ctor ::CallBackEmployee\n"; } bool callback(CallBackEmpInterface* obj1, CallBackEmpInterface* obj2) { cout<<"\n\nCallBackEmployee::callBack \n"; if(obj1->empId() == obj2->empId()) { return(0); //--- } else if(obj1->empId() < obj2->empId()) { return(-1); //--- } else { return(1); //--- } } }; class CallBackEmpContainer { public: CallBackEmpContainer(): basePtr_mpp(NULL) { basePtr_mpp = new (CallBackEmpInterface *)[2]; } void insert(const CallBackEmpInterface *obj_p) { CallBackEmpInterface *tempObj_p; tempObj_p = (CallBackEmpInterface *)obj_p; if(count !=2) { basePtr_mpp[count] = tempObj_p; ++count; } } bool operator () (CallBackEmpInterface* obj1, CallBackEmpInterface* obj2) { cout<<"\nCalling CallBackEmpInterface::operator () ...\n"; return((*basePtr_mpp)->callback(obj1, obj2)); } private: CallBackEmpInterface ** basePtr_mpp; static unsigned int count; }; unsigned int CallBackEmpContainer::count = 0; int main() { cout<<"Implementation of Callback Function using Functor or FunctionObject ...\n"; cout<<"------------------------------------------------------------------------\n\n"; CallBackEmployee *obj1 = new CallBackEmployee(1); CallBackEmployee *obj2 = new CallBackEmployee(2); CallBackEmpContainer cb; cb.insert(obj1); cb.insert(obj2); //To find a object with empId as "1" in the container CallBackEmployee *obj3 = new CallBackEmployee(1); //compare objects empId if (0 == cb(obj1, obj3)) { cout<<"Found the object with empId as "<<obj3->empId()<<"...\n\n" ; } else { cout<<"The container does not have this empId...\n\n"; } delete (obj1); delete (obj2); delete (obj3); return(0); } Output --------- Implementation of Callback Function using Functor or FunctionObject ... ------------------------------------------------------------------------------------- Ctor ::CallBackEmpInterface Ctor ::CallBackEmployee Ctor ::CallBackEmpInterface Ctor ::CallBackEmployee Ctor ::CallBackEmpInterface Ctor ::CallBackEmployee Calling CallBackEmpInterface::operator () ... CallBackEmployee::callBack Found the object with empId as 1... Here in this example, CallBackEmpContainer acts as a Functor, having the implementation for operator( ) with 2 arguments for comparison. This acts as a callback and is used in the main function to find the Employee with specific empId. This is done by creating a temporary criterian object of Employee with that specific empId (that needs to be found) and sent as a argument to operator ( ) function. Hope this article helps in understanding the Callbacks and it's implementation. thanks Mridula. References To know more about Functor or Function Object refer: Prefer Function Objects over Function Pointers http://www.go4expert.com/showthread.php?t=16504