c++中的通知中心

Notification Center in C++

本文关键字:通知 c++      更新时间:2023-10-16

在用iOS和Mac objective C框架编程一段时间后,我开始喜欢上NSNotificationCenter和NSNotification类实现的通用通知模式。回到c++,它一直是我做大多数事情的语言选择,我发现自己在尝试复制这个模式,并且相信应该已经有一个类似的c++类的通用实现提供了对它的支持。

在c++中实现模式似乎比在Objective C中实现要困难一些,因为后者更具动态性,但似乎远非不可能。我已经浏览了boost库,因为它们通常都很棒,很遗憾没有找到我的运气。虽然boost::bind、boost::lamda、boost::函数似乎完成了大部分工作。我错过了什么明显的东西吗?是否有任何已经存在的东西允许我轻松地复制NSNotification/NSNotificationCenter行为?

理论上,您可以创建一个类,该类具有函数指针的向量,以便在调用某个通知时调用——一个类具有字典,其中对象是推送通知时要调用的函数的向量

除了在其他答案中提到的boost包之外,还有一个选项是poco::NotificationCenter

这个实现更接近Cocoa通知框架,正如Poco的文档中具体讨论的那样:

NotificationCenter类基本上是在Apple的Cocoa(或OpenStep)中找到NSNotificationCenter类。

按照@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提供了以下解决方案

但是,如果用户关闭了新闻消息区域,破坏了deliverNews知道的newsMessageArea对象?最有可能的是会出现分段故障。然而,对于Boost。表明一种需要仅使NewsMessageArea可跟踪,并且插槽涉及当newsMessageArea被断开时,newsMessageArea将被断开摧毁。NewsMessageArea类通过派生实现可跟踪从boost::signals::trackable类公开,例如:

struct NewsMessageArea : public MessageArea, public boost::signals::trackable
{
  // ...
};

在这个时候,使用trackable有一个明显的限制进行槽连接的对象:使用提振。的指针或引用被理解为传递给boost::bind的可跟踪对象将被找到并跟踪。