c语言面向对象:事件
2025-11-21 06:49:28 世界杯北京事件与回调的区别:回调函数只能执行一个方法。回调函数本质是一个函数指针。这个指针指向哪个函数,就执行哪个函数。而事件可以注册多个函数。当一个对象激活某个事件,可以有多个响应函数。c语言可以使用一个函数指针列表,实现类似事件的效果。首先实现一个ZEventClass事件类。用于注册事件处理函数和触发事件。ZEventClass.h/***************************** Black Spoor *****************************/#ifndef _BLACKSPOOR_ZEVENTCLASS_H_#define _BLACKSPOOR_ZEVENTCLASS_H_#include
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