1)  观察者模式定义

略,各种设计模式的书上都有定义。

2)  观察者模式一般实现

观察者模式一般实现,都是“被观察者”保存一个“观察者”的列表,循环这个列表来通知“观察者”。代码,其中使用了boost的智能指针shared_ptr:

  1. #include <iostream>
  2. #include <list>
  3. #include "boost/shared_ptr.hpp"
  4. using namespace std;
  5. using namespace boost;
  6. //观察者基类
  7. class Observer
  8. {
  9. public:
  10. //处理被观察者的通知
  11. virtual void update(const int i) = 0;
  12. };
  13. //观察者类A
  14. class ObserverA : public Observer
  15. {
  16. public:
  17. virtual void update(const int i)
  18. {
  19. cout << "ObserverA.update(" << i << ")" << endl;
  20. }
  21. };
  22. //观察者类B
  23. class ObserverB : public Observer
  24. {
  25. public:
  26. virtual void update(const int i)
  27. {
  28. cout << "ObserverB.update(" << i << ")" << endl;
  29. }
  30. };
  31. //被观察者基类
  32. class Subject
  33. {
  34. public:
  35. virtual ~Subject()
  36. {
  37. }
  38. //注册观察者
  39. virtual void reg(const shared_ptr<Observer>& pObs) = 0;
  40. //取消注册观察者
  41. virtual void unreg(const shared_ptr<Observer>& pObs) = 0;
  42. //通知观察者
  43. virtual void notify(const int i) = 0;
  44. };
  45. //被观察者类A
  46. class SubjectA : public Subject
  47. {
  48. public:
  49. virtual void reg(const shared_ptr<Observer>& pObs)
  50. {
  51. m_lstObs.push_back(pObs);
  52. }
  53. virtual void unreg(const shared_ptr<Observer>& pObs)
  54. {
  55. for (list<shared_ptr<Observer> >::iterator it = m_lstObs.begin();
  56. it != m_lstObs.end();)
  57. {
  58. if (pObs == *it) m_lstObs.erase(it++);
  59. else ++it;
  60. }
  61. }
  62. virtual void notify(const int i)
  63. {
  64. for (list<shared_ptr<Observer> >::iterator it = m_lstObs.begin();
  65. it != m_lstObs.end(); ++it)
  66. {
  67. (*it)->update(i);
  68. }
  69. }
  70. protected:
  71. //观察者类别
  72. list<shared_ptr<Observer> > m_lstObs;
  73. };
  74. int main()
  75. {
  76. //被观察者pSubA
  77. shared_ptr<Subject> pSubA(new SubjectA);
  78. //观察者pObsA
  79. shared_ptr<Observer> pObsA(new ObserverA);
  80. //观察者pObsB
  81. shared_ptr<Observer> pObsB(new ObserverB);
  82. //注册pObsA
  83. pSubA->reg(pObsA);
  84. //注册pObsB
  85. pSubA->reg(pObsB);
  86. //通知
  87. pSubA->notify(1);                //显示
  88. //ObserverA.update(1)
  89. //ObserverB.update(1)
  90. //取消pObsA的注册
  91. pSubA->unreg(pObsA);
  92. //通知
  93. pSubA->notify(2);                //显示
  94. //ObserverB.update(2)
  95. return 0;
  96. }

3)  观察者模式Boost.Signals实现

Boost.Signals是基于函数指针或函数对象来实现观察者模式的。其中Boost.Signals2是线程安全版本。代码:

  1. #include <iostream>
  2. #include <list>
  3. #include "boost/shared_ptr.hpp"
  4. #include "boost/signal.hpp"
  5. using namespace std;
  6. using namespace boost;
  7. //使用函数对象来实现
  8. //观察者类A
  9. class ObserverA
  10. {
  11. public:
  12. void operator()(const int i)
  13. {
  14. cout << "ObserverA(" << i << ")" << endl;
  15. }
  16. };
  17. //观察者类B
  18. class ObserverB
  19. {
  20. public:
  21. void operator()(const int i)
  22. {
  23. cout << "ObserverB(" << i << ")" << endl;
  24. }
  25. };
  26. int main()
  27. {
  28. //被观察者sig
  29. signal<void (const int)> sig;
  30. //注册观察者ObserverA
  31. signals::connection connA = sig.connect(ObserverA());
  32. //注册观察者ObserverB
  33. sig.connect(ObserverB());
  34. //通知
  35. sig(1);                 //显示
  36. //ObserverA(1)
  37. //ObserverB(1)
  38. //取消obsA的注册
  39. connA.disconnect();
  40. //通知
  41. sig(2);                 //显示
  42. //ObserverB(2)
  43. return 0;
  44. }

Boost.Signals还支持被观察者分组,可以对整个组进行“通知”、取消注册。另外,Boost.Signals需要编译才能使用。

观察者模式与Boost.Signals的更多相关文章

  1. boost::signals::signal的使用方法

    吃力的讲完boost::signals的ppt.然后接着就是做练习题. 通过讲ppt,发现有一句话说的真好:你自己知道是一回事.你能给别人讲明确又是另外一回事.真的有些东西你自己理解,可是用语言去非常 ...

  2. vs2013 boost signals

    #include "stdafx.h" #include <boost/signals2/signal.hpp> #include <iostream> u ...

  3. Linux上安装使用boost入门指导

    Data Mining Linux上安装使用boost入门指导 获得boost boost分布 只需要头文件的库 使用boost建立一个简单的程序 准备使用boost二进制文件库 把你的程序链接到bo ...

  4. Windows下如何使用BOOST C++库 .

    Windows下如何使用BOOST C++库 我采用的是VC8.0和boost_1_35_0.自己重新编译boost当然可以,但是我使用了 http://www.boostpro.com/produc ...

  5. 以boost::function和boost:bind取代虚函数

    转自:http://blog.csdn.net/Solstice/archive/2008/10/13/3066268.aspx 这是一篇比较情绪化的blog,中心思想是“继承就像一条贼船,上去就下不 ...

  6. Win7下Boost库的安装

    Boost库是C++领域公认的经过千锤百炼的知名C++类库,涉及编程中的方方面面,简单记录一下使用时的安装过程 1.boost库的下载 boost库官网主页:www.boost.org 2.安装 将下 ...

  7. VS2008下直接安装使用Boost库1.46.1版本号

    Boost库是一个可移植.提供源码的C++库,作为标准库的后备,是C++标准化进程的发动机之中的一个. Boost库由C++标准委员会库工作组成员发起,当中有些内容有望成为下一代C++标准库内容.在C ...

  8. VS2008下直接安装使用Boost库1.46.1版本

    Boost库是一个可移植.提供源代码的C++库,作为标准库的后备,是C++标准化进程的发动机之一. Boost库由C++标准委员会库工作组成员发起,其中有些内容有望成为下一代C++标准库内容.在C++ ...

  9. boost事件处理

    尽管这个库的名字乍一看好象有点误导,但实际上并不是如此. Boost.Signals 所实现的模式被命名为 '信号至插槽' (signal to slot).它基于下面概念:当相应的信号被发出时.相关 ...

随机推荐

  1. QT5 r 加入qwtplot3d 三维库

          qwtplot3d是基于QtOpenGL开发的,也是qwt库的三维库,我使用的是qwtplot3d-0.2.7.zip版本.   步骤跟编译qwt库一样(不明白可以看回前面写的一篇文章“Q ...

  2. CSS 定位元素之 relative

    1. relative 和 absolute relative 会限制 absolute. absolute 会根据 父级的的定位元素来定位. 2. overflow 和 absolue 当overf ...

  3. UIApplication的作用

    1.设置app图标右上角的数字2.设置状态栏的属性(样式.是否要显示)3.打开某个链接\发短信\打电话4.keyWindow : 访问程序的主窗口(一个程序只能有一个主窗口)5.windows : 访 ...

  4. 高可用集群(HA)配置

    高可用集群(HA) 1. 准备工作 HA的心跳监测可以通过串口连接监测也可以通过网线监测,前者需要服务器有一个串口,后者需要有一个空闲网卡.HA架构中需要有一个共享的存储设备首先需要在两台机器上安装m ...

  5. Asp.Net HttpApplication 事件汇总

    Global.asax 文件,有时候叫做 ASP.NET 应用程序文件,提供了一种在一个中心位置响应应用程序级或模块级事件的方法.你可以使用这个文件实现应用程序安全性以及其它一些任务.下面让我们详细看 ...

  6. poj1159 dp(滚动数组优化)

    H - 简单dp 例题扩展 Crawling in process... Crawling failed Time Limit:3000MS     Memory Limit:65536KB     ...

  7. Mac添加或修改环境变量

    方式1. 终端添加或修改 命令:pico, vim等 方式:pico .bash_profile 方式2. 文本方式添加或修改 1)打开 touch ~/.bash_profile open -t ~ ...

  8. Java中list<Object>集合去重实例

    一:Java中list去重的方法很多,下面说一下其中一种方法:把list里的对象遍历一遍,用list.contain(),如果不存在就放入到另外一个list集合中: 二:实例 这里需要注意的是:使用c ...

  9. 关于TP的RBAC的使用

    如果你是一个TP的重度使用者的话,请自动略过笔者以下文字 权限管理我在成为一个开发者1年半内,接触过2种,一种就是数学方式 比如我们文件夹权限的755这种权限管理的方式,这种二进制的权限管理的方式 无 ...

  10. python学习第三天 --布尔类型

    我们已经了解了Python支持布尔类型的数据,布尔类型只有True和False两种值,但是布尔类型有以下几种运算: 与运算:只有两个布尔值都为 True 时,计算结果才为 True. True and ...