C++11之用std::function和std::bind实现观察者模式

Posted kaifangqu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++11之用std::function和std::bind实现观察者模式相关的知识,希望对你有一定的参考价值。

使用C++11中的std::bind和std::function以及模板可以很好的实现观察者模式,现在把自己的一些实现的想法记录在此.

编译环境:VS2017

实现的想法:将各个类之间进行解耦,使用C++11的特性实现观察者,C++11中的std::function中可以传函数和lambda仿函数,感觉类似标准之前的回调函数,有时间会去剖析一下该特性.

观察者模式简介:

主体类中维护一个观察者的列表,如果有消息传过来,列表将把所有的消息遍历一遍,一般列表元素是一个父类指针,利用继承的特性实现子类中的相应.

类似于此:

class Subject

public:
    std::vector<Base*>m_vec;
;

利用模板的静态多态去取代继承的动态多态.

如此实现的话会造成各个模块之间的耦合过强,对子类的修改也会影响到父类。

更改的代码如下:

1 使用std::function在调用之前完成对列表元素的添加(可以称之为注册)

2 利用模板实现类型的推导

3 使用std::map来存储数据,用于当作主体中的观察者列表

code 如下:

 1 #include "pch.h"
 2 #include <iostream>
 3 #include <vector>
 4 #include <functional>
 5 #include <map>
 6 
 7 template<typename EVENT>
 8 class Subject
 9 
10 public:
11     template<typename OBSERVER>
12     void registerObser(const EVENT&event, OBSERVER&&observer)
13     
14         m_map_observers[event].push_back(std::forward<OBSERVER>(observer));
15     
16     
17     void notify(const EVENT&event)const
18     
19         for (auto &itor : m_map_observers.at(event))
20         
21             itor();
22         
23     
24 
25 private:
26     std::map<EVENT, std::vector<std::function<void()>>> m_map_observers;
27 ;
28 
29 
30 class Derive1 
31 
32 public:
33     
34     void printMsg()  std::cout << __func__ << std::endl; 
35 ;
36 
37 class Derive2
38 
39 public:
40     void printMsg(int level)  std::cout << __func__ << "level is " << level << std::endl; 
41 ;
42 
43 class VarDef
44 
45 public:
46     VarDef(std::string s1) :m_s1(s1) 
47     VarDef(std::string s1, int level) :m_s1(s1), m_level(level) 
48     std::string m_s1;
49     int m_level;
50     friend bool operator<(const VarDef&left, const VarDef&right)
51     
52         if (left.m_s1 == right.m_s1)
53             return (left.m_level < right.m_level);
54         else
55             return (left.m_s1 < right.m_s1);
56     
57 ;
58 
59 int main()
60 
61     Subject<VarDef> s;
62     
63     s.registerObser(VarDef("Derive1"), std::bind(&Derive1::printMsg, &Derive1()));
64     s.registerObser(VarDef("Derive2", 2), std::bind(&Derive2::printMsg, &Derive2(),2));
65 
66     s.notify(VarDef("Derive2",2));
67 
68     return 0;
69 

实现功能:
维护类VarDef来实现针对不同Message的打印.在该类中需要定义多个构造函数来完成不同的功能.

对外暴露的接口为registerObser,notify,在使用之前需要对多份消息进行注册,当有消息过来时便可以进行通知.

 

以上是关于C++11之用std::function和std::bind实现观察者模式的主要内容,如果未能解决你的问题,请参考以下文章

C++11 std::bind和std::function解析

C++11 std::bind std::function 高级使用方法

C++11 std::bind std::function 变参函数

C++11 std::bind std::function 变参函数

C++11 std::bind函数,std::function函数

C++11的std::function源码解析