广播消息模式

接收广播消息的接口,同时又自己能请求广播

class IBroadcastEvent
{
public:
	friend class Broadcaster;
	IBroadcastEvent() :broadcaster(nullptr){}
	virtual void recvMessage(const std::string& msg) = 0;
	virtual void requestBroadcast(const std::string& msg)
	{
		if (broadcaster)
		{
			broadcaster->sendBroadcastMessage(msg);
		}
	}
protected:
	Broadcaster* broadcaster;
};

发送广播对象

//Header
class Broadcaster
{
public:
	Broadcaster(){}
	~Broadcaster(){ recver_list.clear(); }
	void sendBroadcastMessage(const std::string& msg);
	bool operator +=(IBroadcastEvent*);
	bool operator -=(IBroadcastEvent*);
	inline size_t	getCount()const{ return recver_list.size(); }
private:
	std::set<IBroadcastEvent*>		recver_list;
	void detachMsg(IBroadcastEvent*, const std::string& );
	std::mutex protect_mutex;

};
//Source
bool Broadcaster::operator+=(IBroadcastEvent* e)
{

	if (e)
	{
		std::lock_guard<std::mutex> lck(protect_mutex);
		recver_list.insert(e);
		e->broadcaster = this;
		return true;
	}
	return false;
}

 bool Broadcaster::operator-=(IBroadcastEvent* e)
{
	std::lock_guard<std::mutex> lck(protect_mutex);
	recver_list.erase(e);
	e->broadcaster = nullptr;
	return true;
}

 void Broadcaster::sendBroadcastMessage(const std::string& msg)
{
	for (std::set<IBroadcastEvent*>::iterator iter = recver_list.begin(); iter != recver_list.end(); iter++)
	{
		detachMsg(*iter, msg);
	}
}

 void Broadcaster::detachMsg(IBroadcastEvent* e, const std::string& msg)
{
	e->recvMessage(msg);
}

测试

class Listen : public IBroadcastEvent
{
public:
	Listen(std::string name) :instance_name(name){}
	void recvMessage(const std::string& msg)
	{
		cout <<instance_name<<"----->"<< msg << endl;
	}
private:
	std::string instance_name;
};


class Scan : public IBroadcastEvent
{
public:
	void recvMessage(const std::string& msg)
	{
		 cout<<"I'm a scan ,I recv msg:"<< msg << endl;
	}
};
int main()
{
	
	Broadcaster br;

	Listen le0("0");
	Listen le1("1");
	Listen le2("2");
	Listen le3("3");
	br += &le0;
	br += &le1;
	br += &le1;
	br += &le1;
	br += &le2;
	br += &le3;
	int a = 123;
	br.sendBroadcastMessage("hello");
	cout << "==========================================\n";
	br -= &le2;
	string ss = "123456";
	Scan s;
	br += &s;
	br.sendBroadcastMessage("hi");

	s.requestBroadcast("request");

	getchar();
	return 0;
}

结果

  • 3----->hello
    2----->hello
    1----->hello
    0----->hello
    ==========================================
    I'm a scan ,I recv msg:hi
    3----->hi
    1----->hi
    0----->hi
    I'm a scan ,I recv msg:request
    3----->request
    1----->request
    0----->request

注意事项

Broadcaster 和 IBroadcastEvent是相互调用的,并且使用了类成员函数,c++中提供类的前项申明但是不提供类的成员函数申明,所以为了避免矛盾,将两个类分在两个文件中,注意其中一个通过头文件申明,另一个使用前项申明,在实现文件中包含头文件。

举例:

// a.h
#include "b.h"//使用头文件申明

class A
{
public:
	A();
private:
	B b;
};


// a.cpp
#include "a.h"
A::A(){}

// b.h

class A;//类前项申明

class B
{
public:
	void print(A *);
};

//b.cpp
#include "a.h"
#include "b.h"

void B::print(A *a)
{
	;
}

 

转载于:https://my.oschina.net/pirtt/blog/896019

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值