Login | Register   
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


Tip of the Day
Language: C++
Expertise: Advanced
Sep 15, 2000

Designing a Generic Callback Dispatcher

In many applications, you need a generic class that invokes callback functions regardless of their class type. For example, an even-driven system that needs to call a member function of a GUI component without knowing its actual type. You can create a generic callback class template to streamline this task. Such a template takes the class whose member function is to be called as its first parameter. The second template parameter is a pointer to that class's member function. The trick is that you base the second parameter on the first one, as follows:

 
template < class T, void (T::*F)() > class callback {/**/};

The implementation of the template is relatively simple: it has a reference to T, which is the class whose member function is to be called, a constructor and a member function called execute(), which invokes the callback member function:

 
template < class T, void (T::*F)() >
class callback
{
public:
 callback(T& t) : object(t) {} // assign actual object to T
 void execute() {(object.*F)();}// launch callback function
private:
 T& object;
};

Remember that in order to call a member function through a pointer to member, you must have a reference or pointer to the actual object. This is why the template has a T& as a data member. Now suppose we want to use the callback template to execute a callback member function of class A:

 
class A
{
public:
 void f();
};

Here's how you instantiate the template: a template argument must be a constant expression. Therefore, you can't use a variable as the address of the member function. Instead, use the & operator to take the function's address. Finally, pass the object whose member function you want to be called as the argument for the template object:

 
int main()
{
 A a; // first, create an object
 callback < A, &A::f > c(a); // instantiate template 
 c.execute(); // call callback member function
}

You can use the callback class template with any class type, as long as the member function called has the same signature.

Danny Kalev
 
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap