工具软件   办公软件   操作系统   网络安全   设计在线   程序开发   教程宝典   软件下载   软件论坛
您的位置:软件 > 开发者网络 > 开发工具 > 开发专栏 > C/C++ > 正文
从C++到.NET 揭开多态的面纱
[文章信息]
作者:刘未鹏
时间:2004-12-17
出处:csdn
责任编辑:方舟
[文章导读]
多态是面向对象理论中的重要概念之一,从而也成为现代程序设计语言的一个主要特性
advertisement
热点推荐
· 真没想到VB也可以这样用之指针技术
· 禁止QQ登录的方法
· 给你的XML文件做个数字签名
· ImageReady制作“焰火”小动画
· Java加密和数字签名编程快速入门
[正文]

1 2 3  下一页

  多态是面向对象理论中的重要概念之一,从而也成为现代程序设计语言的一个主要特性,从应用角度来说,多态是构建高灵活性低耦合度的现代应用程序架构所不可忽缺的能力。从概念的角度来说,多态使得程序员可以不必关心某个对象的具体类型,就可以使用这个对象的“某一部分”功能。这个“某一部分”功能可以用基类来呈现,也可以用接口来呈现。后者显得更为重要——接口是使程序具有可扩展性的重要特性,而接口的实现依赖于语言对多态的实现,或者干脆就象征着语言对多态的实现。

  本文并不大算赘述多态的应用,因为其应用实在俯拾皆是,其概念理论也早已完善。这里,我们打算从实现的角度来看一看一门语言在其多态特性的背后做了些什么——知其所以然,使用时方能游刃有余。

  或许你在学习一门语言的时候,曾经对多态的特性很迷惑,虽然教科书上所讲的非常简单,也非常明了——正如它的原本理念一样,但是你也想知道语言(编译器)在背后都干了些什么,为什么一个派生类对象就可以被当作其基类对象来使用?用指向派生类对象的基类指针调用虚函数时凭什么能够精确的到达正确的函数?类的内部是如何布局的?

  我们这样考虑:假设语言不支持多态,而我们又必须实现多态,我们可以怎么做?

  多态的雏形:

class B
{
 public:
  int flag; //为表示简洁,0代表基类,1代表派生类
  void f(){cout<<”in B::f()”;} //非虚函数
};

class D:public B
{
 public:
  void f(){cout<<”in D::f()”;} //非虚函数
};

void call_virtual(B* pb)
{
 if(pb->flag==0) //如果是基类,则直接调用f
  pb->f(); //调用的是基类的f
 else //如果是派生类,则强制转化为派生类指针再调用f
  (D*)pb->f(); //调用的是派生类的f
}

  这样,可以正好符合“根据具体的对象类型调用相应的函数”的理念。但是这个原始方案有一些缺点:;例如,分发“虚函数”的代码要自己书写,不够优雅,不具有可扩展性(当继承体系扩大时,这堆代码将变得臃肿无比),不具有封闭性(如果加入了一个新的派生类,则“虚函数”调用的代码必须作改动,然而如果恰巧这个调用是无法改动的(例如,库函数),则意味着,一个用户加入的派生类将无法兼容于那个库函数)等等。结果就是——这个方案不具有通用性。

  但是,这个方案能够说明一些本质性的问题:flag数据成员用于标识对象所属的具体类型,从而调用者可以根据它来确定到底调用哪个函数。但是,可不可以不必“知道”对象的具体类型就能够调用正确的函数呢?可以,改进的方案如下:

class B
{
 public:
  void (*f)(); //函数指针,派生类对象可以通过给它重新赋值来改变对象的行为
};

class D:public B
{};

void call_virtual(B* pb)
{
 (*(pb->f))(); //间接调用f所指的函数
}

void B_Mem()
{
 cout<<”I am B”;
}

void D_Mem()
{
 cout<<”I am D”;
}

int main()
{
 B b;
 b.f=&B_Mem; //B_Mem代表B的“虚函数”
 D d;
 d.f=&D_Mem; //以D_Mem来覆盖(override)B的虚函数
 call_virtual(&b); //输出“I am B”
 call_virtual(&d); //输出“I am D”
}

  在这个改进的例子中,派生类对象可以通过修改函数指针f的指向,从而获得特定的行为,这里重要的是,call_virtual函数不再需要通过丑陋的if-else语句来判断对象的具体类型,而只是简单的通过一个指针来调用“虚函数”——这时候,如果派生类需要改变具体的行为,则可以将相应的函数指针指向它自己的函数即可,这招“偷梁换柱”通过增加一个间接层的办法“神不知鬼不觉”地将“虚函数”替换(Override)掉了。


1 2 3  下一页

发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容焦点新闻
  • 深入研究 C++中的 STL Deque 容器
  • 明确C++风格的类型转换的用法
  • C++程序设计语言编程风格演变史
  • 深入探讨C++中的引用
  • 利用C++编写一个猜字游戏
  • 民营家电商排队造手机 设备商全面杀入
  • 英特尔澄清杨旭任职传闻 官方没宣布此消息
  • 国资委河北密制联通拆分方案
  • 垃圾邮件害人害企害国 清除垃圾邮件不手软
  • 中兴携手阿尔卡特 全球逐鹿CDMA
  • 用友总裁王文京:誓将ERP变成“大众消费”
  • 香港消费者委员会:数码相机最贵未必最好
  • 外电称中兴正评估西门子手机业务 或能并购
  • Advertisement

    天极无线


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

    CSEEK搜索