工具软件   办公软件   操作系统   网络安全   设计在线   程序开发   教程宝典   软件下载   软件论坛
您的位置:软件 > 开发者网络 > 开发工具 > 开发专栏 > C/C++ > 正文
C++中建立对象间消息连接的系统方法
[文章信息]
作者:项飞
时间:2005-02-23
出处:blog
责任编辑:方舟
[文章导读]
本文提出一种建立对象间消息连接的系统方法
advertisement
热点推荐
· 设计欣赏:《夜精灵》之学会尝试
· 音乐CD完全DIY全程图解
· 2月22日软件精选 Word表格框线设置
· 趋势科技PC-cillin 2005评测报告
· 六大绝招轻松搞定系统更新
[正文]

1 2  下一页

  用过C++进行过面向对象程序设计的用户都知道,程序中的对象很少单独存在。不考虑对象间的相互作用几乎是不可能的。所以,标识对象间的关系或建立对象间的消息连接是面向对象程序设计的一项重要任务。本文着重从C++程序设计的角度,提出一种建立对象间消息连接的实用方法。如果你想详细了解面向对象程序设计技术,请参阅有关专著。

  大家都知道对象是数据和方法的封装体。在C++中,它们分别表现为数据成员和成员函数。程序设计者通过执行对象的各种方法,来改变对象的状态(即改变对象的属性数据)。从而使该对象发生某些“事件”。当一对象发生某事件时,它通常需向其它相关对象发送“消息”,请求它们作出一些处理。 这时,发生事件并向其它对象请求处理的对象被称为“事件对象”,而处理事件的对象被称为“回调对象”。回调对象对事件的处理称为“回调函数”。

  在C++中,这一过程相当于:当事件对象发生事件时,调用回调对象的某些成员函数。通常的作法是回调对象向事件对象传递对象指针。但这种方法不通用。为了减少程序设计的工作量,本文提出一种建立对象间消息连接的系统方法。它的思路是:将“事件发生→请求处理→执行处理”这一过程抽象成一个“回调”(CallBack)类。通过继承,用户可以轻松获取建立对象间消息连接的机制。

  一、回调类的数据结构及其成员函数

  本文提出的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类的使用方法有进一步的了解。

file://测试程序文件:test.cpp

#include"callback.h"

file://“扬声器”类

class Speaker:public CallBack
{
 private:
  int volume;
 public:
  Speaker(int v): volume(v) {}
  void IncreaseVolume(int v) file://增加音量成员函数
  {
   volume += v;
   if(volume > 20){ file://“音量大于20”事件发生了
    file://调用注册在两事件上的回调函数
    CallCallBack("音量改变了");
    CallCallBack("音量大于20", &volume);
   }
  }

 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++玩家共同探讨这类问题。

  联系方式:fei_xiang@263.net


1 2  下一页

天极社区邀请您:写博客日记  上传相片   论坛聊天  订阅电子杂志  推荐网摘   免费图铃工具
笔名:   请您注意:

 遵守国家有关法律、法规,尊重网上道德,承担一切因您的行为而直接或间接引起的法律责任。

 天极网拥有管理笔名和留言的一切权利。
评论:
 
发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容焦点新闻
  • 谈跨平台C++动态连接库的实现
  • 在C++中创建并使用Web服务
  • 利用C++模板编写的序列化框架
  • C语言高效编程的的四大绝招
  • C++高质量编程点滴
  • 惠普发布笔记本策略 称不受卡莉离职影响
  • 美国版权组织称某些软件授权协议侵犯用户权益
  • 郭台铭称霸:鸿海11亿元并购奇美55%股份
  • “英特尔金童”能否撞破英特尔“天花板”?
  • 一亿美金再投中国:易趣成“救命稻草”?
  • 香港首个网上合法付费下载音乐专门店开张
  • 专访SSA总裁Michael:从“先驱”到“先烈”
  • 新闻调查:1000万水货手机入境路线揭密
  • Advertisement

    天极无线


    奇妙科幻|美好风光|清风车影|漫画卡通|星座生肖|明星写真|动物世界
    老鼠爱大米
    挥着翅膀的女孩
    女人味
    栀子花开
    白月光
    刚刚好
    江南
    快乐崇拜
    亲爱的你怎么不在我身边
    小薇
    2002年的第一场雪
    有多少爱可以重来
    我的地盘
    七里香
    情人
     
    老鼠爱大米 老板电话
    冲动的惩罚 七里香
    我不是黄蓉 女生撒娇
    盛夏的果实 坚持到底
    孤单北半球 眉飞色舞
    挪威的森林 可爱女人
    最浪漫的事 老板电话

    CSEEK搜索