Following @anno's recommendation to look at boot::signal, it does after examination seem like a possible option although it is, as expected, not as straight-forward as the objective C solutions. Looking through the boost::signal tutorial, I thought I would go through the most relevant aspects for the problem at hand.
To create notification senders:
Consider a simple news delivery service, where clients connect to a news provider that then sends news to all connected clients as information arrives. The news delivery service may be constructed like this:
class NewsItem { /* ... */ };
boost::signal<void (const NewsItem&)> deliverNews;
The objective of deliverNews
is to inform observers that a NewsItem
has been generated.
Observers can be added as follows (using the boost::bind library):
Clients that wish to receive news updates need only connect a function object that can receive news items to the deliverNews signal. For instance, we may have a special message area in our application specifically for news, e.g.,:
struct NewsMessageArea : public MessageArea
{
public:
// ...
void displayNews(const NewsItem& news) const
{
messageText = news.text();
update();
}
};
// ...
NewsMessageArea newsMessageArea = new NewsMessageArea(/* ... */);
// ...
deliverNews.connect(boost::bind(&NewsMessageArea::displayNews, newsMessageArea, _1));
To address the problem of removing observers which have been deallocated from the list, boost::signal offers the following solution
However, what if the user closes the news message area, destroying the
newsMessageArea object that deliverNews knows about? Most likely, a
segmentation fault will occur. However, with Boost.Signals one need
only make NewsMessageArea trackable, and the slot involving
newsMessageArea will be disconnected when newsMessageArea is
destroyed. The NewsMessageArea class is made trackable by deriving
publicly from the boost::signals::trackable class, e.g.:
struct NewsMessageArea : public MessageArea, public boost::signals::trackable
{
// ...
};
At this time there is a significant limitation to the use of trackable
objects in making slot connections: function objects built using
Boost.Bind are understood, such that pointers or references to
trackable objects passed to boost::bind will be found and tracked.