监听器模式:事件源经过事件的封装传给监听器,当事件源触发事件后,监听器接收到事件对象可以回调事件的方法
观察者模式:观察者(Observer)相当于事件监听者,被观察者(Observable)相当于事件源和事件,执行逻辑时通知observer即可触发oberver的update,同时可传被观察者和参数
观察者模式有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
感知事件的发生只由一个类对象负责,即观察者
对于事件的处理由监听者处理
1.监听者必须要告诉观察者自己关注的事件
2.当消息发生以后通过什么东西告诉监听者事件发生了
so,监听者一般会向观察者注册回调函数,当事件发生后观察者会通过回调函数告诉监听者事件发生了
eg:
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<functional> //函数对象的库
#include<iterator> //迭代器
#include<algorithm> //泛型算法
using namespace std;
class Listener
{
public:
Listener(string name):_name(name){}
virtual void handleMessage(int msg)=0;
protected:
string _name;
};
class Listener1:public Listener
{
public:
Listener1(string name):Listener(name){}
virtual void handleMessage(int msg)
{
cout<<_name<<" recv";
switch(msg)
{
case 0:
cout<<" 0 meg"<<endl;
break;
case 1:
cout<<" 1 meg"<<endl;
break;
case 2:
cout<<" 2 meg"<<endl;
break;
default:
break;
}
}
};
class Listener2:public Listener
{
public:
Listener2(string name):Listener(name){}
virtual void handleMessage(int msg)
{
cout<<_name<<" recv";
switch(msg)
{
case 0:
cout<<" 0 meg"<<endl;
break;
case 2:
cout<<" 2 meg"<<endl;
break;
default:
break;
}
}
};
class Listener3:public Listener
{
public:
Listener3(string name):Listener(name){}
virtual void handleMessage(int msg)
{
cout<<_name<<" recv";
switch(msg)
{
case 0:
cout<<" 0 meg"<<endl;
break;
case 1:
cout<<"1 meg"<<endl;
break;
default:
break;
}
}
};
class Observer
{
public:
void Register(int msgid,Listener *listener)
{
map<int,vector<Listener*>>::iterator it=_observerMap.find(msgid);
if(it==_observerMap.end())
{
vector<Listener*> tmpvec;
tmpvec.push_back(listener);
_observerMap[msgid]=tmpvec;
}
else
it->second.push_back(listener);
}
void Dispatch(int msgid)
{
map<int,vector<Listener*>>::iterator it=_observerMap.find(msgid);
if(it==_observerMap.end())
return;
vector<Listener*>::iterator vit=it->second.begin();
for(;vit!=it->second.end();vit++)
{
(*vit)->handleMessage(msgid);
}
}
private:
map<int,vector<Listener*>> _observerMap;
};
int main()
{
Observer obser;
Listener *p1=new Listener1("listener1");
Listener *p2=new Listener2("listener2");
Listener *p3=new Listener3("listener3");
obser.Register(0,p1);
obser.Register(1,p1);
obser.Register(2,p1);
obser.Register(0,p2);
obser.Register(2,p2);
obser.Register(0,p3);
obser.Register(1,p3);
int msgid;
while(true)
{
cout<<"input msgid:";
cin>>msgid;
if(msgid==-1)
break;
obser.Dispatch(msgid);
}
return 0;
}
运行结果:
but,上面的监听者观察者模式不是线程安全的,因为,对象定义在线程1中,而观察者的handleMessage方法是在线程2中执行的,但是,此时你根本就不知道该对象是否还存在,调用会失败
线程安全的监听者观察者模式:
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<functional> //函数对象的库
#include<iterator> //迭代器
#include<algorithm> //泛型算法
#include<memory> //boost智能指针
using namespace std;
class Listener
{
public:
Listener(string name):_name(name){}
virtual void handleMessage(int msg)=0;
protected:
string _name;
};
class Listener1:public Listener
{
public:
Listener1(string name):Listener(name){}
virtual void handleMessage(int msg)
{
cout<<_name<<" recv";
switch(msg)
{
case 0:
cout<<" 0 meg"<<endl;
break;
case 1:
cout<<" 1 meg"<<endl;
break;
case 2:
cout<<" 2 meg"<<endl;
break;
default:
break;
}
}
};
class Listener2:public Listener
{
public:
Listener2(string name):Listener(name){}
virtual void handleMessage(int msg)
{
cout<<_name<<" recv";
switch(msg)
{
case 0:
cout<<" 0 meg"<<endl;
break;
case 2:
cout<<" 2 meg"<<endl;
break;
default:
break;
}
}
};
class Listener3:public Listener
{
public:
Listener3(string name):Listener(name){}
virtual void handleMessage(int msg)
{
cout<<_name<<" recv";
switch(msg)
{
case 0:
cout<<" 0 meg"<<endl;
break;
case 1:
cout<<"1 meg"<<endl;
break;
default:
break;
}
}
};
class Observer
{
public:
void Register(int msgid,weak_ptr<Listener>listener)
{
map<int,vector<weak_ptr<Listener>>>::iterator it=_observerMap.find(msgid);
if(it==_observerMap.end())
{
vector<weak_ptr<Listener>> tmpvec;
tmpvec.push_back(listener);
_observerMap[msgid]=tmpvec;
}
else
it->second.push_back(listener);
}
void Dispatch(int msgid)
{
map<int,vector<weak_ptr<Listener>>>::iterator it=_observerMap.find(msgid);
if(it==_observerMap.end())
return;
vector<weak_ptr<Listener>>::iterator vit=it->second.begin();
for(;vit!=it->second.end();vit++)
{
//(*vit)->handleMessage(msgid);
//在该线程中想要使用若指针
//将弱指针提升为强智能指针,成功表示该对象还活着,失败返回空
shared_ptr<Listener> p=(*vit).lock();
if(p!=NULL)
{
p->handleMessage(msgid);
}
}
}
private:
map<int,vector<weak_ptr<Listener>>> _observerMap;
};
int main()
{
//监听者的线程代码1
//定义:shared_ptr,
//强智能指针引用对象,对象不会析构,只有强智能指针出了作用域,引起智能指针的析构,
//智能指针给该对象的引用计数减一,这个对象才析构
//在产生对象的线程中,要把共享对象(强智能指针)传给(泄漏)其他线程要用弱指针
//一个对象被强智能指针引用,该对象是不会析构的,弱指针只是观察对象,他可以观察对象是存活还是死亡的
Observer obser;
shared_ptr<Listener> p1(new Listener1("listener1"));
shared_ptr<Listener> p2(new Listener2("listener2"));
shared_ptr<Listener> p3(new Listener3("listener3"));
obser.Register(0,p1);
obser.Register(1,p1);
obser.Register(2,p1);
obser.Register(0,p2);
obser.Register(2,p2);
obser.Register(0,p3);
obser.Register(1,p3);
//观察者线程2
int msgid;
while(true)
{
cout<<"input msgid:";
cin>>msgid;
if(msgid==-1)
break;
obser.Dispatch(msgid);
}
return 0;
}
强弱智能指针解决c++共享对象的线程安全问题:
在定义智能指针对象的地方用强智能指针(强智能指针会对该对象的引用计数加一,强智能指针只要引用对象,对象是不会析构的,只有强智能指针有出了作用域,引起智能指针的析构,才会使该对象的引用计数减一,这个对象才析构),要把共享对象(强智能指针对象)泄漏给其他线程用弱智智能指针(强智能指针只要引用对象,对象是不会析构的,弱指针只是观察对象,他可以观察该对象是存活的还是死亡的),想要在其他线程中使用该对象要先把若智能指针转成强智能指针,用lock(),提升成功表示该对象还活着,提升失败返回空