-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathobserve.cpp
119 lines (106 loc) · 2.61 KB
/
observe.cpp
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
//定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新
//https://blog.csdn.net/m0_61705102/article/details/128138766
#include <iterator>
#include <memory>
#include<mutex>
#include<iostream>
#include<vector>
class Observer;
typedef std::vector<std::weak_ptr<Observer>>::iterator Iterator;//迭代器
//抽象被观察者
class Subject
{
public:
virtual void Attach(std::weak_ptr<Observer>) = 0;//注册观察者对象的接口
virtual Iterator Detach(Iterator it) = 0;//删除观察者对象的接口
virtual void notifyObservers() = 0;//告知所有观察者update
};
//抽象观察者
class Observer
{
public:
virtual void update() = 0;//更新自身状态
};
//被观察者
class ConcreteSubject :public::Subject
{
public:
void Attach(std::weak_ptr<Observer> s)
{
//vector的add是线程安全的
observers_.push_back(s);
}
Iterator Detach(Iterator it)
{
//线程不安全,要在临界区调用此接口
return observers_.erase(it);
}
void notifyObservers()
{
lock.lock();
Iterator it = observers_.begin();
while (it != observers_.end())
{
//先尝试将weak_ptr提升为share_ptr
std::shared_ptr<Observer>obj = it->lock();
if (obj)//提升成功,说明该对象未被其他线程析构
{
obj->update();//更新
++it;
}
else//提升失败,说明该对象已被其他线程析构
{
//从观察者集合中将已被析构对象删除
//因为此处属于临界区,是线程安全的
it = Detach(it);
}
}
lock.unlock();
}
private:
mutable std::mutex lock;
std::vector<std::weak_ptr<Observer>> observers_;//观察者集合
};
//观察者按需求定义即可,需要继承抽象观察者
//以下为例
class Teacher :public::Observer
{
public:
void update()
{
std::cout << "Teacher is update" << std::endl;
}
~Teacher()
{
std::cout << "Teacher is ~" << std::endl;
}
};
class Student :public::Observer
{
public:
void update()
{
std::cout << "Student is update" << std::endl;
}
~Student()
{
std::cout << "Student is ~" << std::endl;
}
};
//int main()
//{
//
// ConcreteSubject subject;
//
// std::shared_ptr<Observer> teacher(new Teacher);
// subject.Attach(teacher);
//
// {
// std::shared_ptr<Observer> student(new Student);
// subject.Attach(student);
// subject.notifyObservers();
// }
//
// subject.notifyObservers();
//
//}