网上看到一些关于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); }
测试结果: