观察者模式(智能指针版)

观察者模式(智能指针版)

用智能指针来码一下观察者模式的代码

当类中有指针成员时,一般有两种方式来管理指针成员:一是采用值型的方式管理,每个类对象都保留一份指针指向的对象的拷贝;另一种更优雅的方式是使用智能指针,从而实现指针指向的对象的共享。

智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象的指针指向同一对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <iostream>
#include <string>
#include <unordered_map>
#include <list>
#include <memory>
#include <cstring>
using namespace std;

class Listen{
public:
Listen(string name):_name(name){}
virtual void handlemessage(int eventid)=0;
protected:
string _name;
};
class Listen1:public Listen{
public:
Listen1(string name):Listen(name){};
void handlemessage(int eventid){
cout<<_name<<" handle messsage";
switch(eventid){
case 1:
cout<<"1"<<endl;
break;
case 2:
cout<<"2"<<endl;
break;
}
}
};
class Listen2:public Listen{
public:
Listen2(string name):Listen(name){};
void handlemessage(int eventid){
cout<<_name<<" handle messsage";
switch(eventid){
case 2:
cout<<"2"<<endl;
break;
case 3:
cout<<"3"<<endl;
break;
}
}
};
class Listen3:public Listen{
public:
Listen3(string name):Listen(name){};
void handlemessage(int eventid){
cout<<_name<<" handle messsage";
switch(eventid){
case 1:
cout<<"1"<<endl;
break;
case 3:
cout<<"3"<<endl;
break;
}
}
};
//定义观察者类型
class Observer{
public:
//注册监听者感兴趣的事件,
void registevent(weak_ptr<Listen> listener,int eventid){
_eventmap[eventid].push_back(listener);
}
//删除监听者感兴趣的事件
void removeevent(weak_ptr<Listen> listener,int eventid){
auto it=_eventmap.find(eventid);//找到这个事件
if(it!=_eventmap.end()){//找到了
auto &mylist=it->second;
for(auto it1=mylist.begin();it1!=mylist.end();++it1){
std::shared_ptr<Listen> a(listener);
std::shared_ptr<Listen> b(*it1);
if(a==b){
mylist.erase(it1);
return ;
}
}
}
}
//eventid事件发生,通知响应的监听者处理事件
void notifyevent(int eventid){
auto it=_eventmap.find(eventid);
if(it!=_eventmap.end()){
auto &mylist =it->second;
for(auto it1(mylist.begin());it1!=mylist.end();){
shared_ptr<Listen> sp=it1->lock();
if(sp!=nullptr){
sp->handlemessage(eventid);
++it1;
}
else{
it1=mylist.erase(it1);
}
}
}
}
private:
//定义成员变量,保存监听者以及它所感兴趣的事件
unordered_map<int,list<weak_ptr<Listen> > >_eventmap;
};
int main()
{
shared_ptr<Listen> p1(new Listen1("aaa"));
shared_ptr<Listen> p2(new Listen2("bbb"));
shared_ptr<Listen> p3(new Listen3("ccc"));

Observer obser;
obser.registevent(p1,1);
obser.registevent(p1,2);
obser.registevent(p2,2);
obser.registevent(p2,3);
obser.registevent(p3,1);
obser.registevent(p3,3);
int eventid;
for(;;)
{
cout<<"eventid :";
cin>>eventid;
obser.notifyevent(eventid);
//p3.~__shared_ptr();
obser.removeevent(p3,3);
}

return 0;
}