附:程序清单(本程序在MS VC++5.0和TC++3.0上均编译通过)
file://回调类的类结构:callback.h
#ifndef _CALLBACK_H
#define _CALLBACK_H
#include<stdlib.h>
#include<string.h>
#include<iostream.h>
#define CALLBACKLIST_INIT_SIZE 10
#define CALLBACKLIST_INCREMENT 5
class CallBack;
typedef void *CallData;//回调数据指针类型定义
typedef void (CallBack::*CallBackFunction)(CallData); file://指向回调成员函数的指针
typedef void (*CallBackStaticFunction)(CallData); file://指向静态成员函数或普通函数的指针类型定义
class EventRecord{ private: char *eventName; file://回调事件名称 CallBack *pointerToCBO;//指向回调对象的指针 file://指向成员函数的指针和指向静态成员函数(或普通函数)指针的共用体 union{ CallBackFunction pointerToCBF; CallBackStaticFunction pointerToCBSF; }; public: EventRecord(void); file://事件记录类的缺省构造函数 file://构造包含成员函数的事件记录 EventRecord(char *ename,CallBack *pCBO,CallBackFunction pCBF); file://构造包含静态成员函数或普通函数的事件记录 EventRecord(char *ename,CallBackStaticFunction pCBSF); ~EventRecord(void);//析构事件记录 void operator = (const EventRecord& er);//重载赋值运算符 file://判断当前事件记录的事件名是否为ename
int operator == (char *ename) const;
file://判断当前事件记录是否和指定事件记录相等
int operator == (const EventRecord& er) const;
void Flush(void); file://将当前事件记录清空
int IsEmpty(void) const;//判断事件记录是否为空(即事件名是否为空)
friend class CallBack; file://让CallBack类能访问EventRecord的私有成员;
};
class CallBack { private: EventRecord *callBackList; file://回调事件表 int curpos; file://当前事件记录位置 int lastpos; file://回调表中最后一空闲位置 int size; file://回调表的大小
void MoveFirst(void) { curpos = 0; }//将当前记录置为第一条记录 void MoveNext(void) file://将下一条记录置为当前记录 { if(curpos == lastpos) return; curpos++; }
file://判断回调表是否被遍历完
int EndOfList(void) const { return curpos == lastpos; } public: CallBack(void);//构造函数 CallBack(const CallBack& cb);//拷贝构造函数 ~CallBack(void);//析构函数
void operator = (const CallBack& cb);// 重载赋值运算符
file://将回调对象的成员函数、静态成员函数(或普通函数) file://注册为事件对象的回调函数
void AddCallBack(char *event,CallBackFunction cbf,CallBack *p); void AddCallBack(char *event,CallBackStaticFunction cbsf); file://删除注册在指定事件上的回调函数
void RemoveCallBack(char *event,CallBackFunction cbf,CallBack *p); void RemoveCallBack(char *event,CallBackStaticFunction cbsf); void RemoveCallBack(char *event);// 删除某事件的全部记录
file://执行注册在某一事件上的所有回调函数
void CallCallBack(char *event, CallData calldata = NULL);
};
#endif
file://回调类的实现:callback.cpp
#include"callback.h"
file://EventRecord类的实现
EventRecord::EventRecord(void) { eventName = NULL; pointerToCBO = NULL; file://因为sizeof(CallBackFunction) > sizeof(CallBackStaticFunction) pointerToCBF = NULL; }
EventRecord::EventRecord(char *ename, CallBack *pCBO, CallBackFunction pCBF) :pointerToCBO(pCBO), pointerToCBF(pCBF) { eventName = strdup(ename); }
EventRecord::EventRecord(char *ename, CallBackStaticFunction pCBSF) :pointerToCBO(NULL), pointerToCBSF(pCBSF) { eventName = strdup(ename); }
EventRecord::~EventRecord(void) { if(eventName) delete eventName; }
void EventRecord::operator = (const EventRecord& er) { if(er.eventName) eventName = strdup(er.eventName); else eventName = NULL; pointerToCBO = er.pointerToCBO; pointerToCBF = er.pointerToCBF; }
int EventRecord::operator == (char *ename) const { if((eventName == NULL)||ename == NULL) return eventName == ename; else return strcmp(eventName,ename) == 0; }
int EventRecord::operator == (const EventRecord& er) const { return (er == eventName) /*er和eventname不能交换位置*/ &&(pointerToCBO == er.pointerToCBO) &&(pointerToCBO ? (pointerToCBF == er.pointerToCBF): (pointerToCBSF == er.pointerToCBSF)); }
void EventRecord::Flush(void) { if(eventName){ delete eventName; eventName = NULL; } pointerToCBO = NULL; pointerToCBF = NULL; }
int EventRecord::IsEmpty(void) const { if(eventName == NULL) return 1; else return 0; }
file://Callback类的实现 CallBack::CallBack(void) { file://按初始尺寸为回调表分配内存空间
callBackList = new EventRecord[CALLBACKLIST_INIT_SIZE];
if(!callBackList){ cerr<<"CallBack: memory allocation error."<<endl; exit(1); } size = CALLBACKLIST_INIT_SIZE; lastpos = 0; curpos = 0; }
CallBack::CallBack(const CallBack& cb): curpos(cb.curpos),lastpos(cb.lastpos),size(cb.size) { callBackList = new EventRecord[size]; if(!callBackList){ cerr<<"CallBack: memory allocation error."<<endl; exit(1); } file://一一复制各条事件记录 for(int i = 0; i < size; i++) callBackList[i] = cb.callBackList[i]; }
void CallBack::operator = (const CallBack& cb) { curpos = cb.curpos; lastpos = cb.lastpos; size = cb.size; delete [] callBackList;//删除旧的回调表 callBackList = new EventRecord[size];//重新分配内存空间 if(!callBackList){ cerr<<"CallBack: memory allocation error."<<endl; exit(1); }
file://一一复制各条事件记录
for(int i = 0; i < size; i++) callBackList[i] = cb.callBackList[i]; }
CallBack::~CallBack(void) { delete [] callBackList; }
void CallBack::AddCallBack(char *event, CallBackFunction pCBF, CallBack *pCBO) { file://如事件名为空,退出 if( (event == NULL)?1:(strlen(event) == 0)) return; file://寻找因删除事件记录而产生的第一个空闲位置,并填写新事件记录 for(int start=0;start<lastpos;start++) if(callBackList[start].IsEmpty()){ callBackList[start] = EventRecord(event,pCBO,pCBF); break; } if(start < lastpos) return; file://确实存在空闲位置 file://没有空闲位置,在回调表后追加新记录 if(lastpos == size) file://回调表已满,需“伸长” { EventRecord *tempList = callBackList;//暂存旧回调表指针 file://以一定的步长“伸长”回调表 callBackList = new EventRecord[size + CALLBACKLIST_INCREMENT]; if(!callBackList){ cerr<<"CallBack: memory allocation error."<<endl; exit(1); } file://复制旧回调表中的记录 for(int i = 0; i < size; i++) callBackList[i] = tempList[i]; delete [] tempList;//删除旧回调表 size += CALLBACKLIST_INCREMENT;//记下新回调表的尺寸 } file://构造新的事件记录并将其填入回调表中 callBackList[lastpos] = EventRecord(event,pCBO,pCBF); lastpos++; } void CallBack::AddCallBack(char *event,CallBackStaticFunction pCBSF) { if( (event == NULL)?1:(strlen(event) == 0)) return; for(int start=0;start<lastpos;start++) if(callBackList[start].IsEmpty()){ callBackList[start] = EventRecord(event,pCBSF); break; } if(start < lastpos) return; file://a hole is found if(lastpos == size) file://event list is insufficient { EventRecord *tempList = callBackList; callBackList = new EventRecord[size + CALLBACKLIST_INCREMENT];
if(!callBackList){ cerr<<"CallBack: memory allocation error."<<endl; exit(1); } for(int i = 0; i < size; i++) callBackList[i] = tempList[i]; delete [] tempList; size += CALLBACKLIST_INCREMENT; }
callBackList[lastpos] = EventRecord(event,pCBSF); lastpos++; }
file://删除注册在指定事件上的成员函数
void CallBack::RemoveCallBack(char *event, CallBackFunction pCBF, CallBack *pCBO) { if( (event == NULL)?1:(strlen(event) == 0)) return; EventRecord er(event,pCBO,pCBF);
for(int i = 0; i < lastpos; i++) if(callBackList[i] == er) callBackList[i].Flush(); }
file://删除注册在指定事件上的静态成员函数或普通函数
void CallBack::RemoveCallBack(char *event,CallBackStaticFunction pCBSF) { if( (event == NULL)?1:(strlen(event) == 0)) return; EventRecord er(event,pCBSF);
for(int i = 0; i < lastpos; i++) if(callBackList[i] == er) callBackList[i].Flush(); }
file://删除注册在指定事件上的所有回调函数
void CallBack::RemoveCallBack(char *event) { if( (event == NULL)?1:(strlen(event) == 0)) return; for(int i = 0; i < lastpos; i++) if(callBackList[i] == event) callBackList[i].Flush(); }
void CallBack::CallCallBack(char *event, CallData callData) { if( (event == NULL)?1:(strlen(event) == 0)) return; CallBack *pCBO; CallBackFunction pCBF; CallBackStaticFunction pCBSF; MoveFirst(); while(!EndOfList()) { file://如当前事件记录和指定事件不匹配,转入下一条记录继续循环 if(!(callBackList[curpos] == event)) { MoveNext(); continue; } file://如找到匹配记录 pCBO = callBackList[curpos].pointerToCBO; file://如事件记录中回调对象指针为空,说明该记录中保存的是静态函数指针 if(pCBO == NULL){ pCBSF = callBackList[curpos].pointerToCBSF; pCBSF(callData);//调用该静态回调函数 } else file://如事件记录中回调对象指针非空,说明该记录中保存的是成员函数指针 { pCBF = callBackList[curpos].pointerToCBF; (pCBO->*pCBF)(callData);// 调用该回调对象的成员函数 } MoveNext(); } } |
 
2/2 首页 上一页 1 2 |