Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 一般观察者模式_C++_C++11_Observer Pattern - Fatal编程技术网

C++ 一般观察者模式

C++ 一般观察者模式,c++,c++11,observer-pattern,C++,C++11,Observer Pattern,我正在使用代码,它有很多观察者模式实现。所有这些活动的组织方式如下: 将由观察员实施的一些接口: class ObserverInterface { virtual void FooOccurs() = 0; }; 实现注册、取消注册和通知的某些类: class ObservableImpl { public: Register(ObserverInterface *observer); Unregister(ObserverInterface *observer);

我正在使用代码,它有很多观察者模式实现。所有这些活动的组织方式如下:

将由观察员实施的一些接口:

class ObserverInterface {
  virtual void FooOccurs() = 0;
};
实现注册、取消注册和通知的某些类:

class ObservableImpl {
  public:
    Register(ObserverInterface *observer);
    Unregister(ObserverInterface *observer);

  private:
    void SomeMethod() {
      // foo things
      for(auto &observer: observers) {
        observer.FooOccurs();
      }
    }
};
每次都有一个注册和注销的拷贝粘贴,以及observer接口的每个方法的通知实现。每当程序员必须记住调用Unregister()时,如果它的观察者将被破坏

我希望将观察者模式包含在两个类模板中。到目前为止,我得到了类似的信息:


但我不确定我是不是在重新发明轮子。有什么更简单的、众所周知的方法可以做到这一点吗?

在C++11中,我建议使用基于令牌的方法

你注册了一个观察员。观察者只是一个
std::函数

注册函数返回一个令牌,
std::shared\u ptr
。只要返回的
shared_ptr
有效,广播公司将继续向该侦听器广播

监听器现在负责维护
std::shared_ptr
生命周期

在广播机内部,您可以在广播前按住
弱\u ptr
.lock()
将其锁定。如果我真的不需要注销(通常我不需要),我会懒洋洋地清理我的
weak\u ptr
s列表。否则,
shared\u ptr
I return有一个删除函数,用于取消注册


或者,您的侦听器是
共享的\u ptr
,并且在内部将
弱的\u ptr
存储到相同的位置

在这个模型中,您不能轻易地注入unregistraton函数。但是,这确实意味着他们可以自己使用别名构造函数将回调的生存期紧密绑定到自己身上,假设它们是由共享的ptr管理的

根据我的经验,只要让侦听器维护一个
std::vector
就足够了。如果他们有更复杂的倾听关系,他们可以做更多的工作,维护钥匙等等

混合模式也是可能的


对于非线程安全的广播,这两种方法都是可以接受的,并且可以用几十行代码编写

线程安全广播变得棘手。我经常发现您最好使用消息传递模式来实现这一点,而不是使用替代方案,因为这稍微降低了对并发性进行推理的难度


这也不适用于你想随意注册听众的情况,广播员和听众的一生就像爆米花一样。

请查看。它可能不适合java样式的代码库,但它是C++中实现观察者模式的一种常见的、众所周知的方法。