C++中建立对象间消息连接的系统方法
}
}
void DecreaseVolume(int v) file://降低音量成员函数
{
volume -= v;
if(volume < 5){ file://“音量小于5”事件发生了
file://调用注册在两事件上的回调函数
CallCallBack("音量改变了");
CallCallBack("音量小于5", &volume);
}
}
};
file://“耳朵”类
class Ear : public CallBack
{
public:
static void Response(CallData callData) file://对“音量改变”的反应
{
cout<<"音量改变了."<<endl;
}
void HighVoiceResponse(CallData callData)//对高音的反应
{
cout<<”喂!太吵了!现在音量是:"<<*((int *)callData)<<endl;
}
void LowVoiceResponse(CallData callData)// 对低音的反应
{
cout<<"啊!我听不清了。现在音量是:"<<*((int *)callData)<<endl;
}
};
void main(void)
{
Speaker s(10); file://现在音量为10
Ear e;
file://为事件对象s注册回调函数
s.AddCallBack("音量大于20”,(CallBackFunction)&Ear::HighVoiceResponse,&e);
s.AddCallBack("音量小于5”,(CallBackFunction)&Ear::LowVoiceResponse,&e);
s.AddCallBack("音量改变了",(CallBackStaticFunction)&Ear::Response);
s.IncreaseVolume(12);//将音量增加12,现在音量位22
s.DecreaseVolume(20);//将音量减少20,现在音量位2
}
运行结果:
音量改变了.
喂!太吵了!现在音量是:22
音量改变了.
啊!我听不清了。现在音量是:2
在上例中,扬声器对象s为事件对象,耳朵对象e为回调对象。。s上被注册了三个事件:“音量改变了”,“音量大于20”,“音量小于5”。 回调函数分别为:Ear::Response, Ear::HighVoiceResponse,Ear::LowVoiceResponse。当扬声器s通过其成员函数IncreaseVolume和 DecreaseVolume改变音量时,回调对象e会自动作出反应。可见,通过使用CallBack类,在对象间建立消息连接已变为一项很简单和优美的工作。
由于笔者水平有限,该类的设计必有不完善之处。如果您对它感兴趣,笔者可与各位C++玩家共同探讨这类问题。
附:程序清单(本程序在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"
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, CallBackStat

