HOME> 世界杯北京> c语言面向对象:事件

c语言面向对象:事件

2025-11-21 06:49:28     世界杯北京    

事件与回调的区别:回调函数只能执行一个方法。回调函数本质是一个函数指针。这个指针指向哪个函数,就执行哪个函数。而事件可以注册多个函数。当一个对象激活某个事件,可以有多个响应函数。c语言可以使用一个函数指针列表,实现类似事件的效果。首先实现一个ZEventClass事件类。用于注册事件处理函数和触发事件。ZEventClass.h/***************************** Black Spoor *****************************/#ifndef _BLACKSPOOR_ZEVENTCLASS_H_#define _BLACKSPOOR_ZEVENTCLASS_H_#include #include "ZListClass.h"typedef struct ZEventClass{ //记录事件处理函数的列表 ZListClass * zlist; //事件的名称 char * eventName; //临界值 线程安全 CRITICAL_SECTION cs; void (*Init)(struct ZEventClass *); void (*Dispose)(struct ZEventClass *); //增加事件处理函数 void (*AddEventMethod)(struct ZEventClass *, void *); //删除事件处理函数 void (*DelEventMethod)(struct ZEventClass *, void *); //枚举事件处理函数 void (*EnumEventMethod)(struct ZEventClass *,void *); //设置事件名称 void (*SetEventName)(struct ZEventClass *, char *); //枚举方法使用的回调函数 void(*CallbackEnumEventMethod)(void *, void *);}ZEventClass;extern ZEventClass * ZEventClassCreate(void);#endif

ZEventClass.c/***************************** Black Spoor *****************************/#include "ZEventClass.h"static void Init(struct ZEventClass *);static void Dispose(struct ZEventClass *);static void AddEventMethod(struct ZEventClass *, void *);static void DelEventMethod(struct ZEventClass *, void *);static void EnumEventMethod(struct ZEventClass *, void *);static void SetEventName(struct ZEventClass *, char *);static void Init(struct ZEventClass * stu){ InitializeCriticalSection(&stu->cs); stu->zlist = ZListClassCreate(); stu->zlist->Init(stu->zlist);}static void Dispose(struct ZEventClass * stu){ if (stu->eventName != NULL) { free(stu->eventName); } stu->zlist->Dispose(stu->zlist); DeleteCriticalSection(&stu->cs);}//增加事件处理函数//method :事件处理函数。 类型是函数指针。static void AddEventMethod(struct ZEventClass * stu, void * method){ EnterCriticalSection(&stu->cs); { ZListItemClass * zinsertitem = ZListItemClassCreate(); zinsertitem->content = method; stu->zlist->PushItem(stu->zlist, zinsertitem); } LeaveCriticalSection(&stu->cs);}//删除事件处理函数//method :事件处理函数。 类型是函数指针。static void DelEventMethod(struct ZEventClass * stu, void * method){ EnterCriticalSection(&stu->cs); { ZListItemClass * zitem = stu->zlist->SearchContent(stu->zlist, method); if (zitem != NULL) { stu->zlist->RemoveItem(stu->zlist, zitem); zitem->Dispose(zitem); } } LeaveCriticalSection(&stu->cs);}//枚举事件处理函数//eventOwner : 事件的拥有者,即包含了ZEventClass的类。static void EnumEventMethod(struct ZEventClass * stu,void * eventOwner){ EnterCriticalSection(&stu->cs); { ZListItemClass * item = stu->zlist->first; while (item != NULL) { if (stu->CallbackEnumEventMethod != NULL) { stu->CallbackEnumEventMethod(eventOwner, item->content); } item = item->next; } } LeaveCriticalSection(&stu->cs);}//设置事件名称static void SetEventName(struct ZEventClass * stu, char * name){ int len = strlen(name); stu->eventName = (char *)malloc(len + 1); memset(stu->eventName, 0, len + 1); memcpy(stu->eventName, name, len);}ZEventClass * ZEventClassCreate(void){ ZEventClass * stu = (ZEventClass *)malloc(sizeof(ZEventClass)); memset(stu, 0, sizeof(ZEventClass)); stu->Init = Init; stu->Dispose = Dispose; stu->AddEventMethod = AddEventMethod; stu->DelEventMethod = DelEventMethod; stu->EnumEventMethod = EnumEventMethod; return stu;}然后实现一个事件触发类ZEventActiveClass,演示如何定义一个事件。ZEventActiveClass类每2秒使计数器加一,并触发一个事件。

ZEventActiveClass.h/***************************** Black Spoor *****************************/#ifndef _BLACKSPOOR_ZEVENTACTIVECLASS_H_#define _BLACKSPOOR_ZEVENTACTIVECLASS_H_#include "stdio.h"#include "ZListClass.h"#include "ZThreadClass.h"#include "ZEventClass.h"typedef struct ZEventActiveClass{ //继承线程类 ZThreadClass thread; ZThreadClass * threadptr; //事件类,用于管理事件处理函数 ZEventClass * timerEvent; //内部计数器 int timerEventCount; void(*Init)(struct ZEventActiveClass *); void(*Dispose)(struct ZEventActiveClass *);}ZEventActiveClass;//定义一个名称为 OnTimerEvent 的函数,相当于C#定义一个委托typedef void (*OnTimerEvent)(struct ZEventActiveClass *, int);extern ZEventActiveClass * ZEventActiveClassCreate(void);#endif

ZEventActiveClass.c/***************************** Black Spoor *****************************/#include "ZEventActiveClass.h"static void Init(struct ZEventActiveClass *);static void Dispose(struct ZEventActiveClass *);static void CreateResource(void *);static void DoSomething(void *);static void CallbackTimerEventMethod(void * eventOwner, void * method);static void Init(struct ZEventActiveClass * stu){ ZThreadClass * th = &(stu->thread); ZThreadClassInit(th); th->Init(th); th->SetThreadName(th, "Timer Event Thread."); th->obj = stu; th->VirtualCreateResource = CreateResource; th->VirtualDoSomething = DoSomething; stu->timerEvent = ZEventClassCreate(); stu->timerEvent->Init(stu->timerEvent); //为事件类的回调函数赋值 stu->timerEvent->CallbackEnumEventMethod = CallbackTimerEventMethod;}static void Dispose(struct ZEventActiveClass * stu){ stu->threadptr->Stop(stu->threadptr); stu->timerEvent->Dispose(stu->timerEvent); free(stu);}//重写线程类的方法 : 建立资源static void CreateResource(void * obj){ ZEventActiveClass * stu = (ZEventActiveClass *)obj; //计数器清零 stu->timerEventCount = 0;}//重写线程类的方法 :线程执行的任务static void DoSomething(void * obj){ ZEventActiveClass * stu = (ZEventActiveClass *)obj; //计数器加一 stu->timerEventCount++; //枚举事件处理函数,触发事件,执行处理事件的回调函数:CallbackTimerEventMethod stu->timerEvent->EnumEventMethod(stu->timerEvent,stu); //等待2秒 stu->thread.ZSleep(2000);}//处理事件的回调函数static void CallbackTimerEventMethod(void * eventOwner, void * method){ ZEventActiveClass * stu = (ZEventActiveClass *)eventOwner; //将枚举的函数转换为OnTimerEvent类型 OnTimerEvent ote = (OnTimerEvent)method; if (ote != NULL && stu!= NULL) { ote(stu, stu->timerEventCount); }}ZEventActiveClass * ZEventActiveClassCreate(void){ ZEventActiveClass * stu = (ZEventActiveClass *)malloc(sizeof(ZEventActiveClass)); memset(stu, 0, sizeof(ZEventActiveClass)); stu->Init = Init; stu->Dispose = Dispose; stu->threadptr = &stu->thread; return stu;}有了事件类ZEventClass和产生事件的类ZEventActiveClass,在下面的主程序代码中,将使用多个处理函数响应事件,演示一个完整的事件示例。 main.c#include #include "ZThreadClass.h"#include "ZEventClass.h"#include "ZEventActiveClass.h"//事件处理函数3void thirdEventMethod(ZEventActiveClass * stu, int count){ printf(" thirdEventMethod %s count = %d\n", stu->thread.threadName, stu->timerEventCount);}//事件处理函数2void secondEventMethod(ZEventActiveClass * stu, int count){ printf(" secondEventMethod %s count = %d\n", stu->thread.threadName, stu->timerEventCount);}//事件处理函数1void firstEventMethod(ZEventActiveClass * stu, int count){ printf(" firstEventMethod %s count = %d\n",stu->thread.threadName, stu->timerEventCount);}void main(void){ ZEventActiveClass * zea = ZEventActiveClassCreate(); zea->Init(zea); //注册事件处理函数 zea->timerEvent->AddEventMethod(zea->timerEvent, secondEventMethod); zea->timerEvent->AddEventMethod(zea->timerEvent, thirdEventMethod); zea->timerEvent->AddEventMethod(zea->timerEvent, firstEventMethod); //开始线程,每2秒触发一次事件 zea->threadptr->Start(zea->threadptr); //等待10秒 zea->threadptr->ZSleep(10000); printf("\n按任意键退出..... \n"); getchar(); printf("\n正在退出..... \n"); zea->threadptr->Stop(zea->threadptr); zea->Dispose(zea);}main函数的输出:开始线程: [Timer Event Thread.] 。 firstEventMethod Timer Event Thread. count = 1 thirdEventMethod Timer Event Thread. count = 1 secondEventMethod Timer Event Thread. count = 1 firstEventMethod Timer Event Thread. count = 2 thirdEventMethod Timer Event Thread. count = 2 secondEventMethod Timer Event Thread. count = 2 firstEventMethod Timer Event Thread. count = 3 thirdEventMethod Timer Event Thread. count = 3 secondEventMethod Timer Event Thread. count = 3 firstEventMethod Timer Event Thread. count = 4 thirdEventMethod Timer Event Thread. count = 4 secondEventMethod Timer Event Thread. count = 4 firstEventMethod Timer Event Thread. count = 5 thirdEventMethod Timer Event Thread. count = 5 secondEventMethod Timer Event Thread. count = 5 firstEventMethod Timer Event Thread. count = 6 thirdEventMethod Timer Event Thread. count = 6 secondEventMethod Timer Event Thread. count = 6按任意键退出..... firstEventMethod Timer Event Thread. count = 7 thirdEventMethod Timer Event Thread. count = 7 secondEventMethod Timer Event Thread. count = 7 firstEventMethod Timer Event Thread. count = 8 thirdEventMethod Timer Event Thread. count = 8 secondEventMethod Timer Event Thread. count = 8正在退出..... [Timer Event Thread.] 线程停止。