C/C++的函数名和函数指针的关系剖析 观察者模式

http://www.cnblogs.com/Esfog/archive/2012/04/23/2467249.html
最近在看观察者模式的时候,看到的一篇,感觉有点感觉。
在项目中使用的是lua,在观察者模式当中,是有一个事件ID和与这个事件ID绑定的函数(与其说是函数倒不如说是函数指针),这些全部存储在一个全局的对象的table当中,一个事件ID下绑定了很多的函数名(也就是函数指针),在触发了某个事件ID之后,只需要调用这个全局对象当中的一个触发函数,就可以循环触发与这个这个事件ID绑定的函数。

// 事件id
#define ENENT_ID_MIN 0
#define EVENT_ID_SHOWSELF 1
#define ENENT_ID_MAX 2

class EventBase
{
public:
	virtual void OnExecute(int nEventId) = 0;
};

class EventSystem
{
public:
	struct EventStruct
	{
		// 注册绑定的数组
		list<EventBase*> arrEventBase;

		EventStruct()
		{
			arrEventBase.clear();
		}
	};

	vector<EventStruct> arrEventStruct;
	int arrEventIndex[ENENT_ID_MAX] = {0};
	int narrCount = 0;

public:
	// 注册
	bool Resister(int nEventId, EventBase* objEventBase = nullptr)
	{
		if (nEventId < ENENT_ID_MIN || nEventId > ENENT_ID_MAX)
		{
			return false;
		}

		if (nullptr == objEventBase)
		{
			return false;
		}

		// 等于0就说明第一次定义,就直接放进去就好
		if (arrEventIndex[nEventId] == 0)
		{
			narrCount++;

			EventStruct eventStruct;
			eventStruct.arrEventBase.push_back(objEventBase);

			arrEventStruct.push_back(eventStruct);

			arrEventIndex[nEventId] = narrCount;

		}
		else
		{
			int nIndex = arrEventIndex[nEventId] - 1;

			if (nIndex > arrEventStruct.size())
			{
				return false;
			}

			EventStruct* peventStruct = &(arrEventStruct[nIndex]);

			auto iter = peventStruct->arrEventBase.begin();
			for (; iter != peventStruct->arrEventBase.end(); iter++)
			{
				// 重复注册
				if ((*iter) == objEventBase)
				{
					return false;
				}
			}

			peventStruct->arrEventBase.push_back(objEventBase);
		}

		return true;
	}

	// 反注册
	bool UnResister(int nEventId, EventBase* objEventBase = nullptr)
	{
		if (nEventId < ENENT_ID_MIN || nEventId > ENENT_ID_MAX)
		{
			return false;
		}

		if (nullptr == objEventBase)
		{
			return false;
		}

		if (arrEventIndex[nEventId] != 0)
		{
			int nIndex = arrEventIndex[nEventId] - 1;
			if (nIndex > arrEventStruct.size())
			{
				return false;
			}

			EventStruct* peventStruct = &(arrEventStruct[nIndex]);

			auto iter = peventStruct->arrEventBase.begin();
			for (; iter != peventStruct->arrEventBase.end(); iter++)
			{
				// 重复注册
				if ((*iter) == objEventBase)
				{
					peventStruct->arrEventBase.erase(iter);
					break;
				}
			}
		}

		return true;
	}

	// 触发
	bool Throw(int nEventId)
	{
		if (nEventId < ENENT_ID_MIN || nEventId > ENENT_ID_MAX)
		{
			return false;
		}

		if (arrEventIndex[nEventId] != 0)
		{
			int nIndex = arrEventIndex[nEventId] - 1;
			if (nIndex > arrEventStruct.size())
			{
				return false;
			}

			EventStruct* peventStruct = &(arrEventStruct[nIndex]);

			auto iter = peventStruct->arrEventBase.begin();
			for (; iter != peventStruct->arrEventBase.end(); iter++)
			{
				(*iter)->OnExecute(nEventId);
			}

			return true;
		}
	}
};

class Person
{
public:
	string strName;			// 姓名
	string strSex;			// 性别
	int nAge;               // 年龄
	string strProfession;   // 职业

public:

	void Create(string _strName, string _strSex, int _Age, string _strProfession)
	{
		strName = _strName;
		strSex = _strSex;
		nAge = _Age;
		strProfession = _strProfession;
	}
};

class Doctor :public Person,public EventBase
{
public:
	void OnExecute(int nEvent)
	{
		if (nEvent == EVENT_ID_SHOWSELF)
		{
			cout << strName << "是一个" << nAge << "岁的" << strSex << "性" << strProfession << endl;
		}
	}
};

class Police :public Person, public EventBase
{
public:
	void OnExecute(int nEvent)
	{
		if (nEvent == EVENT_ID_SHOWSELF)
		{
			cout << strName << "是一个" << nAge << "岁的" << strSex << "性" << strProfession << endl;
		}
	}
};

static EventSystem* peventSystem = nullptr;
EventSystem* GetEventSystemObj()
{
	if (peventSystem == nullptr)
	{
		peventSystem = new EventSystem;
	}

	return peventSystem;
}

int main(void)
{
	EventSystem* pObj = GetEventSystemObj();
	if (pObj == nullptr)
	{
		cout << "事件系统对象出错" << endl;
		return 0;
	}

	Police police1;
	police1.Create("小刚", "男", 26, "警察");
	Police police2;
	police2.Create("小红", "女", 22, "警察");

	Doctor doctor1;
	doctor1.Create("小明", "男", 34, "儿科医生");
	Doctor doctor2;
	doctor2.Create("小丽", "女", 28, "护士");

	pObj->Resister(EVENT_ID_SHOWSELF, static_cast<EventBase*>(&police1));
	pObj->Resister(EVENT_ID_SHOWSELF, static_cast<EventBase*>(&doctor1));

	pObj->Throw(EVENT_ID_SHOWSELF);

	pObj->UnResister(EVENT_ID_SHOWSELF, static_cast<EventBase*>(&police1));
	pObj->Resister(EVENT_ID_SHOWSELF, static_cast<EventBase*>(&police2));

	pObj->Throw(EVENT_ID_SHOWSELF);

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值