class CriticalErrorHandler {public: virtual ~CriticalErrorHandler(){} virtual void handle() = 0;};class ErrorHandler {public: void addCriticalErrorHandler( CriticalErrorHandler * c ) { criticals.push_back(c); } void onCriticalError() {std::for_each(criticals.begin(),criticals.end(),std::mem_fun(&CriticalErrorHandler::handle)); }private: std::vector<CriticalErrorHandler *> criticals;};class Window {public: void close(){ std::cout << "closing window!" << std::endl; }};class CloseWindowOnCriticalError : public CriticalErrorHandler {public: CloseWindowOnCriticalError( Window *window ) : window(window) {} virtual void handle() { window->close(); }private: Window *window;};int main(){ Window window; ErrorHandler errors; errors.addCriticalErrorHandler( new CloseWindowOnCriticalError(&window) ); errors.onCriticalError();}
Note how the Window knows nothing about the ErrorHandler and the ErrorHandler knows nothing of the window. Using boost we could clean it up with smart pointers etc. This is a simplified example. Boost has signals and slots stuff too, but I haven't really used them (most of the stuff I do with events like that is in Lua, so everything is just a Lua function).