本文最后更新于:2020年6月30日 晚上

** *本篇总结一下基于多线程的线程安全的观察者监听者模式。。。→_→ **

在阅读本文之前,需要先了解相关知识。。请戳传送门——智能指针的交叉引用问题及解决方法

#include <iostream>
#include <string>
#include <memory>
#include <map>
#include <vector>
using namespace std;

template <typename T>
bool operator==(const weak_ptr<T> &left, const weak_ptr<T> &right)
{
	return left.lock() == right.lock();
}

class Listener
{
public:
	Listener(string name) :_name(name) {}
	virtual void handleMessage(int msgid) = 0;
	string _name;
};

class Listener1 : public Listener
{
public:
	Listener1(string name) :Listener(name) {}
	void handleMessage(int msgid)
	{
		cout << _name << " ";
		switch (msgid)
		{
		case 0:
			cout << " recv 0 msg!" << endl;
			break;
		case 1:
			cout << " recv 1 msg!" << endl;
			break;
		case 2:
			cout << " recv 2 msg!" << endl;
			break;
		}
	}
};

class Listener2 : public Listener
{
public:
	Listener2(string name) :Listener(name) {}
	void handleMessage(int msgid)
	{
		cout << _name << " ";
		switch (msgid)
		{
		case 0:
			cout << " recv 0 msg!" << endl;
			break;
		case 2:
			cout << " recv 2 msg!" << endl;
			break;
		}
	}
};

class Listener3 : public Listener
{
public:
	Listener3(string name) :Listener(name) {}
	void handleMessage(int msgid)
	{
		cout << _name << " ";
		switch (msgid)
		{
		case 1:
			cout << " recv 1 msg!" << endl;
			break;
		case 2:
			cout << " recv 2 msg!" << endl;
			break;
		}
	}
};

class Observer
{
public:
	void registerListener(weak_ptr<Listener> lp, int msgid)
	{
		map<int, vector<weak_ptr<Listener>>>::iterator it = _ObserMap.find(msgid);
		if (it == _ObserMap.end())
		{
			vector<weak_ptr<Listener>> vec;
			vec.push_back(lp);
			_ObserMap.insert(make_pair(msgid, vec));
		}
		else
		{
			it->second.push_back(lp);
		}
	}

	void deleteListener(weak_ptr<Listener> lp, int msgid)
	{
		map<int, vector<weak_ptr<Listener>>>::iterator it = _ObserMap.find(msgid);
		if (it != _ObserMap.end())
		{
			vector<weak_ptr<Listener>>::iterator vecIt = find(it->second.begin(), it->second.end(), lp);
			if (vecIt != it->second.end())
				it->second.erase(vecIt);
		}
	}

	void dispatchMessage(int msgid)
	{
		map<int, vector<weak_ptr<Listener>>>::iterator it = _ObserMap.find(msgid);
		if (it != _ObserMap.end())
		{
			vector<weak_ptr<Listener>>::iterator vecIt = it->second.begin();
			for (; vecIt != it->second.end(); ++vecIt)
			{
				shared_ptr<Listener> lp = (*vecIt).lock();
				if (lp != NULL) 
					lp->handleMessage(msgid);
			}
		}
	}
private:
	map<int, vector<weak_ptr<Listener>>> _ObserMap;
};

int main()
{
	shared_ptr<Listener> p1(new Listener1("Listener1"));
	shared_ptr<Listener> p2(new Listener1("Listener2"));
	shared_ptr<Listener> p3(new Listener1("Listener3"));

	Observer obser;
	obser.registerListener(p1, 0);
	obser.registerListener(p1, 1);
	obser.registerListener(p1, 2);
	obser.registerListener(p2, 0);
	obser.registerListener(p2, 2);
	obser.registerListener(p3, 1);
	obser.registerListener(p3, 2);

	//obser.deleteListener(p1, 2);

	while (true)
	{
		int msgid;
		cout << "msgid:";
		cin >> msgid;
		obser.dispatchMessage(msgid);
	}
	return 0;
}

写代码时候的坑:代码坑