网上看到一些关于C++模拟和C#类似的Event处理,这里记录一下:
新建一个event.h头文件:
#pragma once
template <typename Handler>
class event
{
private:
Handler m_Handler;
protected:
//模拟C# event 的add/remove访问器
//如果要重新实现add/remove请在派生类中重写这两个函数
virtual void add(const Handler value) { m_Handler = value; };
virtual void remove(const Handler value) { if (value == m_Handler)m_Handler = NULL; };
public:
//构造函数
event() : m_Handler(NULL) {}
//+= 操作符
event& operator += (const Handler value)
{
add(value);
return *this;
}
//-=操作符
event& operator -= (const Handler value)
{
remove(value);
return *this;
}
//PFN_EVENT_HANDLE 操作符
operator Handler()
{
return m_Handler;
}
};
再建一个类:MyClass.h
#pragma once
#include "stdafx.h"
//定义EventHandler的函数指针类型
typedef void(*EventHandler)(char* testChar);
class MyClass
{
public:
//构造函数
MyClass() {};
//声明一个事件
event<EventHandler> AEvent;
//激发事件
void FireEvent(char* testChar)
{
if (AEvent != NULL)
{
//C++中必须用EventHandler进行强制类型转换
((EventHandler)AEvent)(testChar);
};
}
};
注意添加引用(位于stdafx.h),根据实际情况自行添加:
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include "event.h"
#include "MyClass.h"
// TODO: 在此处引用程序需要的其他头文件
主函数测试代码:
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
void MyEventHandler1(char* testChar);
void MyEventHandler2(char* testChar);
int main()
{
MyClass Obj;
char* test1 = "aaaaaa\n";
char* test2 = "bbbbbb\n";
Obj.AEvent += MyEventHandler1;//定制事件
Obj.FireEvent(test1);//这行将导致MyEventHandler1被调用
Obj.AEvent += MyEventHandler2;//定制事件
Obj.FireEvent(test2);//这行将导致已订阅的:MyEventHandler1和MyEventHandler2 都被调用
Obj.AEvent -= MyEventHandler1;//撤消事件
Obj.FireEvent(test1);//这行将导致剩下的MyEventHandler2被调用
Obj.AEvent -= MyEventHandler2;//撤消事件
Obj.FireEvent(test2);//这个将不会引发事件
return 0;
}
void MyEventHandler1(char* testChar)
{
printf("MyEventHandler 1 : ");
printf(testChar);
}
void MyEventHandler2(char* testChar)
{
printf("MyEventHandler 2 : ");
printf(testChar);
}
测试结果: