C ++ 11观察者模式(信号,时隙,事件,更改广播器/侦听器或任何您想调用的方式)

问题描述 投票:34回答:5

通过C ++ 11中的更改​​(例如包含std::bind),是否存在一种推荐的方法来实现简单的单线程观察者模式,而无需依赖于核心语言或标准库(例如boost::signal)?

编辑

[如果有人发布一些代码来显示如何使用新的语言功能来减少对boost::signal的依赖,那将仍然非常有用。

c++ boost c++11 signals observer-pattern
5个回答
28
投票

我认为bind使创建槽位变得更加容易(参见'preferred' syntax vs. the 'portable' syntax-一切都将消失)。但是,观察者的管理并没有变得那么复杂。

但是作为@R。 Martinho Fernandes提到:现在可以轻松创建std::vector<std::function< r(a1) > >,而无需为(人工)“纯虚拟”接口类麻烦。


根据要求:关于连接管理的想法-可能充满了错误,但是您会明白的:

3
投票
因为您要输入代码,所以我的博客条目Performance of a C++11 Signal System包含基于C ++ 11功能的功能齐全的信号系统的单文件实现,而没有更多的依赖关系(尽管是单线程,这是性能要求) 。

这是一个简短的用法示例:

Signal<void (std::string, int)> sig2; sig2() += [] (std::string msg, int d) { /* handler logic */ }; sig2.emit ("string arg", 17);


2
投票
我编写了自己的轻量级Signal / Slot类,该类返回连接句柄。面对异常情况,现有答案的键系统非常脆弱。您在使用显式调用删除内容时必须格外小心。我更喜欢将RAII用于开/关对。

我的库中明显缺乏支持的是从调用中获得返回值的能力。我相信boost :: signal具有计算总返回值的方法。在实践中,通常您不需要这样做,而我只是觉得它很混乱,但是将来我可能会想出一种返回方法来使之有趣,例如练习。

关于我的类的一件很酷的事情是Slot和SlotRegister类。 SlotRegister提供了一个公共接口,您可以安全地链接到一个专用插槽。这样可以防止外部对象调用观察者方法。它很简单,但是封装不错。


0
投票
我本人也对此有所尝试。我的努力可以在这个要点上找到,它将继续发展。 。 。

https://gist.github.com/4172757

我使用不同的样式,与BOOST信号相比,它更类似于JUCE中的更改通知。连接管理是使用一些lambda语法完成的,该语法通过副本进行捕获。到目前为止,它运行良好。


0
投票
这是我想出的。

这假定不需要汇总广播信号的侦听器的结果。同样,“ slot”或Signal :: Listener是回调的所有者。这应该与您(我猜...)lambda可能捕获的对象一起使用,以便当该对象超出范围时,回调也将超出范围,从而防止再次调用它。

您也可以使用其他答案中描述的方法,以可以查找的方式存储侦听器所有者对象。

© www.soinside.com 2019 - 2024. All rights reserved.