本篇内容主要讲解“C++程序设计如何建立对象间消息连接”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++程序设计如何建立对象间消息连接”吧!
10余年建站经验, 成都做网站、网站制作客户的见证与正确选择。成都创新互联提供完善的营销型网页建站明细报价表。后期开发更加便捷高效,我们致力于追求更美、更快、更规范。
一、回调类的数据结构及其成员函数
本文提出的CallBack类支持三种回调函数。它们是:回调对象中的成员函数,属于回调类的静态成员函数和普通的C函数。CallBackle类中包含一回调函数表callBackList。它用于记录事件名称,指向回调函数及回调对象的指针。该表的每一个节点为一个事件记录EventRecord。每个事件记录包含三个域:事件名指针eventName,指向回调对象的指针pointerToCBO,指向回调函数的指针pointerToCBF或pointerToCBSF(其中,pointerToCBF指向回调对象的成员函数,pointerToCBSF指向回调类的静态成员函数或普通函数。它们同处于一共用体内)。CallBack类所提供的回调机制是这样的:在事件对象上注册回调对象中的回调函数;当事件发生时,事件对象在其回调表中检索并执行回调函数。从而使二者的消息连接得以建立。(关于该类的具体实现,请参阅文后所附的程序清单)
事件名 | 回调对象指针 | 回调函数指针 |
“event” | pointerCBO | pointerToCBF或pointerTOCBSF |
AddCallBack: 注册事件名和指向回调函数,回调对象的指针
CallCallBack: 在回调表中,检索注册在指定事件上回调函数并调用它们
事件发生时,调用CallCallBack函数
对事件event进行处理的成员函数
从CallBack类继承的回调表callBackList, 成员函数AddCallBack和CallCallBack。
当回调函数为静态成员函数或普通C函数时, pointerToCBO为NULL。
事件名是回调表callBackLis中的检索关键字。
回调对象中其它成员函数
CallBack类的成员函数AddCallBack用来将回调函数注册到事件对象的回调表中。它有两个重载版本:
void CallBack::AddCallBack(char *event,CallBackFunction cbf,CallBack *p); void CallBack::AddCallBack(char *event,CallBackStaticFunction cbsf);
其中,***个AddCallBack用来将某回调对象的成员函数注册到事件对象的回调表中。第二个AddCallBack用来将或某回调类的静态成员函数注册到事件对象的回调表中。在上参数表中,event是指向事件名字符串的指针,p是指向回调对象的指针,cbf和cbsf分别是指向成员函数及静态成员函数(或普通函数)的指针。当回调函数来自某回调对象SomeObject时,传递成员函数指针应采用如下格式:(CallBackFunction)&SomeObject::MemberFunctionName; 传递SomeObject类的某静态成员函数指针应采用格式:(CallBackStaticFunction)& SomeObject::FunctionName;传递程序中普通函数指针时,只需传递函数名即可。
CallBack类的成员函数void CallBack::CallCallBack(char *ename, CallData calldata = NULL)用来调用注册在事件ename上的所有回调函数。其中,calldata为数据指针(CallData实际上就是void*,详见程序清单)。事件对象可通过它向回调对象传递有用的数据。该成员函数通常在事件对象的成员函数中调用,因为通常只有事件对象的成员函数才能改变对象的内部数据,从而使某些事件发生。
成员函数RemoveCallback用来删除注册在事件对象上的回调函数。它的三个重载版本依次为:
void CallBack::RemoveCallBack(char *event,CallBackFunction cbf,CallBack *p); void CallBack::RemoveCallBack(char *event,CallBackStaticFunction cbsf); void CallBack::RemoveCallBack(char *event);
其中,event,cbf,cbsf,p等参数和成员函数AddCallBack中各参数一样。***个RemoveCallBack用于删除注册在事件event上某回调对象的一个成员函数。第二个RemoveCallBack用于删除注册在事件event上的某普通函数或某回调类的一个静态成员函数。第三个RemoveCallBack用于删除注册在事件event上的全部回调函数。
二、CallBack类的使用方法
使用CallBack类,可按以下步骤进行:
1.确定程序中哪些对象间存在关系,需要建立消息连接。并确定在各特定消息连接关系中,哪个对象是事件对象,哪个对象是回调对象。
2.事件对象类和回调对象类都必须从CallBack类继承,以获得回调支持。
3.为事件对象注册回调数据。包括:事件名,回调函数名,指向回调对象的指针。
4.当你感兴趣的事件发生时,在事件对象类引发事件的成员函数中调用CallCallBack函数。
下面是一个具体的例子。通过它你会对Callback类的使用方法有进一步的了解。
//测试程序文件:test.cpp #include"callback.h" //“扬声器”类 class Speaker:public CallBack { private: int volume; public: Speaker(int v): volume(v) {} void IncreaseVolume(int v) //增加音量成员函数 { volume += v; if(volume > 20){ //“音量大于20”事件发生了 //调用注册在两事件上的回调函数 CallCallBack("音量改变了"); CallCallBack("音量大于20", &volume); } } void DecreaseVolume(int v) //降低音量成员函数 { volume -= v; if(volume < 5){ //“音量小于5”事件发生了 //调用注册在两事件上的回调函数 CallCallBack("音量改变了"); CallCallBack("音量小于5", &volume); } } }; //“耳朵”类 class Ear : public CallBack { public: static void Response(CallData callData) //对“音量改变”的反应 { cout<<"音量改变了."<运行结果:
音量改变了.
喂!太吵了!现在音量是:22
音量改变了.
啊!我听不清了。现在音量是:2
在上例中,扬声器对象s为事件对象,耳朵对象e为回调对象。。s上被注册了三个事件:“音量改变了”,“音量大于20”,“音量小于5”。 回调函数分别为:Ear::Response, Ear::HighVoiceResponse,Ear::LowVoiceResponse。当扬声器s通过其成员函数IncreaseVolume和 DecreaseVolume改变音量时,回调对象e会自动作出反应。可见,通过使用CallBack类,在对象间建立消息连接已变为一项很简单和优美的工作。
附:程序清单(本程序在MS VC++5.0和TC++3.0上均编译通过)
//回调类的类结构:callback.h #ifndef _CALLBACK_H #define _CALLBACK_H #include#include #include #define CALLBACKLIST_INIT_SIZE 10 #define CALLBACKLIST_INCREMENT 5 class CallBack; typedef void *CallData;//回调数据指针类型定义 typedef void (CallBack::*CallBackFunction)(CallData); //指向回调成员函数的指针 typedef void (*CallBackStaticFunction)(CallData); //指向静态成员函数或普通函数的指针类型定义 class EventRecord{ private: char *eventName; //回调事件名称 CallBack *pointerToCBO;//指向回调对象的指针 //指向成员函数的指针和指向静态成员函数(或普通函数)指针的共用体 union{ CallBackFunction pointerToCBF; CallBackStaticFunction pointerToCBSF; }; public: EventRecord(void); //事件记录类的缺省构造函数 //构造包含成员函数的事件记录 EventRecord(char *ename,CallBack *pCBO,CallBackFunction pCBF); //构造包含静态成员函数或普通函数的事件记录 EventRecord(char *ename,CallBackStaticFunction pCBSF); ~EventRecord(void);//析构事件记录 void operator = (const EventRecord& er);//重载赋值运算符 //判断当前事件记录的事件名是否为ename int operator == (char *ename) const; //判断当前事件记录是否和指定事件记录相等 int operator == (const EventRecord& er) const; void Flush(void); //将当前事件记录清空 int IsEmpty(void) const;//判断事件记录是否为空(即事件名是否为空) friend class CallBack; //让CallBack类能访问EventRecord的私有成员; }; class CallBack { private: EventRecord *callBackList; //回调事件表 int curpos; //当前事件记录位置 int lastpos; //回调表中***一空闲位置 int size; //回调表的大小 void MoveFirst(void) { curpos = 0; }//将当前记录置为***条记录 void MoveNext(void) //将下一条记录置为当前记录 { if(curpos == lastpos) return; curpos++; } //判断回调表是否被遍历完 int EndOfList(void) const { return curpos == lastpos; } public: CallBack(void);//构造函数 CallBack(const CallBack& cb);//拷贝构造函数 ~CallBack(void);//析构函数 void operator = (const CallBack& cb);// 重载赋值运算符 //将回调对象的成员函数、静态成员函数(或普通函数) //注册为事件对象的回调函数 void AddCallBack(char *event,CallBackFunction cbf,CallBack *p); void AddCallBack(char *event,CallBackStaticFunction cbsf); //删除注册在指定事件上的回调函数 void RemoveCallBack(char *event,CallBackFunction cbf,CallBack *p); void RemoveCallBack(char *event,CallBackStaticFunction cbsf); void RemoveCallBack(char *event);// 删除某事件的全部记录 //执行注册在某一事件上的所有回调函数 void CallCallBack(char *event, CallData calldata = NULL); }; #endif //回调类的实现:callback.cpp #include"callback.h" //EventRecord类的实现 EventRecord::EventRecord(void) { eventName = NULL; pointerToCBO = NULL; //因为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; } //Callback类的实现 CallBack::CallBack(void) { //按初始尺寸为回调表分配内存空间 callBackList = new EventRecord[CALLBACKLIST_INIT_SIZE]; if(!callBackList){ cerr<<"CallBack: memory allocation error."< *pCBF)(callData);// 调用该回调对象的成员函数 } MoveNext(); } } 到此,相信大家对“C++程序设计如何建立对象间消息连接”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
分享文章:C++程序设计如何建立对象间消息连接
浏览地址:http://cdxtjz.cn/article/jdpcid.html