Следуя рекомендации @anno взглянуть на boot::signal, после изучения он кажется возможным вариантом, хотя, как и ожидалось, он не так прост, как объективные решения C. Просматривая руководство по boost::signal, я думал, что пройдусь по наиболее важным аспектам проблемы.
Чтобы создать отправителей уведомлений:
Рассмотрим простую службу доставки новостей, где клиенты подключаются к поставщику новостей, который затем отправляет новости всем подключенным клиентам по мере поступления информации. Служба доставки новостей может быть построена следующим образом:
class NewsItem { /* ... */ };
boost::signal<void (const NewsItem&)> deliverNews;
Целью deliverNews
является информирование наблюдателей о том, что NewsItem
был сгенерирован.
Наблюдателей можно добавить следующим образом (используя библиотеку boost::bind):
Клиентам, которые хотят получать обновления новостей, нужно только подключить функциональный объект, который может получать новости, к сигналу DeliverNews. Например, у нас может быть специальная область сообщений в нашем приложении специально для новостей, например:
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));
Чтобы решить проблему удаления наблюдателей, которые были освобождены из списка, boost::signal предлагает следующее решение.
Однако что, если пользователь закроет область сообщения новостей, уничтожив объект newsMessageArea, о котором знает deliveryNews? Скорее всего, произойдет ошибка сегментации. Однако с Boost.Signals нужно только сделать NewsMessageArea отслеживаемым, и слот, связанный с newsMessageArea, будет отключен при уничтожении newsMessageArea. Класс NewsMessageArea становится отслеживаемым путем публичного унаследования от класса boost::signals::trackable, например:
struct NewsMessageArea : public MessageArea, public boost::signals::trackable
{
// ...
};
В настоящее время существует существенное ограничение на использование отслеживаемых объектов при создании слотовых соединений: объекты-функции, созданные с использованием Boost.Bind, понимаются таким образом, что указатели или ссылки на отслеживаемые объекты, переданные в boost::bind, будут найдены и отслежены.
person
jbat100
schedule
05.11.2011