Table of Contents
There are many situations in which it is desirable to decouple code that detects an event, and the code that deals with it. This is especially common in GUI programming, where a toolkit might provide user interface elements such as clickable buttons but, being a generic toolkit, doesn't know how an individual application using that toolkit should handle the user clicking on it.
In C the callbacks are generally handled by the application calling a
'register' function and passing a pointer to a function and a
void clicked(void *data); button * okbutton = create_button("ok"); static char somedata = "This is some data I want the clicked() function to have"; register_click_handler(okbutton, clicked, somedata);
When clicked, the toolkit will call
clicked() with the data pointer passed
This works in C, but is not typesafe. There is no compile-time way of
clicked() isn't expecting a struct of some sort instead of a
As C++ programmers, we want type safety. We also want to be able to use things other than free-standing functions as callbacks.
libsigc++ provides the concept of a slot, which holds a reference to one of the things that can be used as a callback:
- A free-standing function as in the example
- A functor objects that defines operator()
- A pointer-to-a-member-function and an instance of an object on which to invoke it (the
object should inherit from
All of which can take different numbers and types of arguments.
To make it easier to construct these, libsigc++ provides the sigc::ptr_fun() and sigc::mem_fun() functions, for creating slots from static functions and member functions, respectively. They return
signal::slot type that can be invoked with
For the other side of the fence, libsigc++ provides
signals, to which the
client can attach
slots. When the
signal is emitted, all the connected
slots are called.