So, I tend to disagree with Uri, somewhat.
If you are implementing the Observer pattern, what you want is to be able to say:
"When object X does Y, I want to execute code Z".
Going with an approach based purely on an abstract class is not the best way to do that. Requiring a separate class (especially in C++) for every event handler is overkill. If you come from Java, that's how they do everything. However Java has 2 features that makes this only slightly annoying: anonymous class, and "instance" member classes. This allows you to define multiple handlers for multiple events in the same class. You have to prefix the methods with "class {", but you can do it.
C++ does not have either anonymous classes or "instance" member classes. This makes using an abstract class for events much more cumbersome if you have multiple handlers that need to share state. You have to do the equivalent of closure generation by hand, which can get pretty irritating pretty quickly.
.NET uses delegates for event handling, which are basically type safe function pointers. They make the code for handling events very straight forward. Unlike function pointers in C++, however, a delegate unifies member function pointers and static function pointers. Basically it can curry the "this" parameter of any member function, leaving a function pointers that looks just like a static function pointer. This means that the type of the object handling the event is not part of the event "interface". That makes it very flexible.
You can't do that directly using C++ member function pointers because the "this" type ends up being a part of the function pointer type, thus limiting your handlers to only appearing within the current class.
The best solution for C++ is a hybrid between the two. What you want is a generic interface like this:
class EventHandler
{
public:
virtual void Handle() = 0;
};
And then an implementation for member functions like this
template <class T>
class MemberFuncEventHandler : public EventHandler
{
public:
MemberFuncEventHandler(T * pThis, void (T::*pFunc)()) : m_pThis(pThis), m_pFunc(pFunc)
{
}
void Handle()
{
(m_pThis->*m_pFunc)();
}
private:
T* m_pThis;
void (T::*m_pFunc)();
};
template <class T>
EventHandler * Handler(T * pThis, void (T::*pFunc)())
{
return new MemberFuncEventHandler<T>(pThis, pFunc);
}
You can also similarly define a handler class for static methods. Then you can just do things like this:
Handlers += Handler(obj, &(c1::foo));
Handlers += Handler(obj, &(c2::bar));
Handlers += Handler(blaa); // for static methods...