CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C++ 语言

C++必知必会-第2章-多态

楼主fiftymetre(50米深蓝)2006-04-05 13:01:07 在 C/C++ / C++ 语言 提问

条款2  
   
  多态  
   
  多态(polymorphism)在一些编程教程中被弄得很神秘,而在另一些教程中则被忽略,其实它不过是C++语言所支持的一个简单而有用的概念。按照C++标准所言,“多态类型(polymorphic   type)”就是带有虚函数的类类型(class   type)。从设计的角度来看,“多态对象(polymorphic   object)”就是一个具有不止一种类型的对象,而“多态基类(polymorphic   base   class)”则是一个为了满足多态对象的使用需求而设计的基类。  
   
  让我们来看一个金融期权的类型AmOption,,如图1所示。  
   
                Dea1                 Priceable  
   
                      /\                     /\  
                          \                 /  
                              Option  
                            /\           /\  
    /                 \  
            AmOption               EurOption  
   
   
  图1   在一个金融期权层次结构中多态的作用。AmOption有四种类型  
   
  AmOption对象同时具有四种类型:AmOption、Option、Deal以及Priceable。由于一个类型是一组操作(参见“数据抽象[条款1]”和“能力查询[条款27]”),因此,AmOption对象可以通过其4个接口中的任何一个进行操纵。这意味着一个AmOptionr   的实现利用或复用所有那些代码。对于AmOption这样的多态类型,从基类继承的最重要的东西就是它们的接口,而不是它们的实现。事实上,一个基类仅仅由接口组成不但常见,而且通常正是我们所希望的(参见“能力查询[条款27]”)。  
   
  当然,这里是一个需要注意的地方。如果让这种优势能够发挥出来,一个良好设计的多态类对于它的每一个基类而言必须是可替换的。换句话说,如果针对option接口编写的通用代码接受的是一个AmOption对象,那么该对象的行为最好就像一个option对象!  
   
  这并不是说AmOption对象应该和Option对象的行为完全一致(首先可能是因为Option基类的许多操作是不带任何实现的纯虚函数)。实际上,将一个多态基类(如Option)想象成一份契约更好理解一些。这个基类对其接口的用户做了某些承诺,这些承诺包括郑重的语法承诺,即特定的成员函数可以通过一些特定类型的实参进行调用,以及不太容易验证的语义上的承诺,即当一个特定的成员函数被调用时将会发生什么实际情况。像AmOption和EurOption这样的具体派生类被称为“转包者”,它们实现Option与其实户签订的契约,如图2所示。  
   
   
   
   
  针对Option接口编写的代码-----Option  
                                                                price()  
                                                                update()  
                                                              /\               /\  
                                                            /                     \  
                                        AmOption                         EurOption  
                                        Price()                               price()  
   
  图2 一个多态的承包者及其“转包者”  
   
  举个例子,如果Option具有一个纯虚成员函数price,其作用是给出Option的当前值,那么AmOption和EurOption都必须实现这个函数。我们显然不会为这两种类型的Option实现完全一致的行为,但它们都应该计算并返回一个价格(price),而不应该去拔打一个电话或打印一份文件。  
   
  另一方面,如果我要去访问同一个对象的两种不同接口的price函数,那么我们应该得到相同的结果。就本质而言,每一个调用都应该绑定到同一个函数:  
   
  AmOption     *d   =   new   AmOption;  
  Option   *b   =   d;  
  d->price();   //如果一个调用的是AmOption::price……………  
  b->price();   //……那么这一个也应该如此!  
   
  这是有意义的(在高级面向对象编程中,竟然有如此之多的基本常识被费解的语法所掩盖)。假如我问你“那个美国期权的当前值是什么?”,我期望得到与以下简短提问方法相同的答案:“那个期权的当前值是什么?”  
   
  当然,同样的推理也适用于对象的非虚拟函数:  
  b->updata()   ;     //如果这一个调用的是Option::updata…….  
  d->updata()   ;     //……那么这一个也是如此!  
   
  正是基类提供的契约允许针对基类接口编写的“多态”代码对特定的期权起作用,同时有助于对派生类的存在保持“健康的不知情”。换句话说,多态代码可能正在操纵AmOption和EurOption对象,但除非特别关心它们到底是什么对象,否则均被视作Option对象。各种各样“具体的”Option类型可以被添加或删除而不会影响到只关心基类Option的通用代码。比方说,如果在某一个地方出现一个AsianOption对象,那么只知道Option的多态代码也能够操作它,这全托“对其具体类型不知情”的福,如果以后这个对象消失了,也犯不着去挂念它。  
   
  出于同样的原因,像AmOption和EurOption这样具体的期权类型只需要知道基类就可以了(它们实现了基类的契约),改变通用代码对它们也毫无影响。原则上,基类可以不知道除自身以外的任何事物。从实践的角度来看,对其接口的设计要考虑预期用户的需求,并且应该以这样的方式进行设计:派生类可以很容易地推知并实现其契约(参见“Template   Method模式[条款22]”)。然而,基类应该对其派生类的具体细节全然不知,因为知道这些会不可避免地致使在类层次结构上添加或删除派生类变得困难。  
   
  和生活中一样,在面向对象设计中,“不知情”或“忽略”也是天赐之福(参见“虚构造函数与Prototype模式[条款29]”和“Factory   Method模式[条款30]”)。  
   
   
   
   
  hi   Fiftymetre,  
   
  很开心你喜欢这本书,祝阅读快乐。  
   
  Solstice说的没错,你的行为我可以理解:)  
   
  Royal  
   
   
   
  //此为荣耀的回信,我也不知道到底许不许我发呵呵,但我是这样理解的“杀之有理,但情有可原”  
   
  希望大家,把你的焦点放在学习上。 问题点数:0、回复次数:35Top

1 楼fiftymetre(50米深蓝)回复于 2006-04-05 13:02:30 得分 0

/\                     /\  
    \                   /  
   
  这样的东东为箭头,呵呵总是对不齐:)  
  Top

2 楼healer_kx(甘草(楼主揭贴吧,我们这些上班灌水的也不容易))回复于 2006-04-05 13:02:58 得分 0

师姐,偶支持你,但是下次记得散分哦。Top

3 楼BluntBlade(信仰迷离·重构之道,在于Redo/Undo之间)回复于 2006-04-05 13:03:19 得分 0

研究,切磋。Top

4 楼iamcaicainiao(老菜,长征)回复于 2006-04-05 13:03:40 得分 0

嘿嘿。Top

5 楼Wolf0403(废人:独活十年~心如刀割)回复于 2006-04-05 13:07:45 得分 0

呃。。江湖。。  
   
  对着荣耀拜一个……Top

6 楼lbing7(向青润老大学习!!!)回复于 2006-04-05 13:35:02 得分 0

大姐的学习笔记?  
   
  收藏一下...Top

7 楼ouyh12345(五岭散人)回复于 2006-04-05 13:47:15 得分 0

学习Top

8 楼cutenoob(cute )回复于 2006-04-05 15:07:58 得分 0

不错了Top

9 楼Torrice(酷爱C++)回复于 2006-04-05 15:24:07 得分 0

dingTop

10 楼pangdae(不学)回复于 2006-04-05 15:35:16 得分 0

一点建议:就是楼主在把原文打出来的同时,希望能把自己的学习体会写在每一条款的后面,大家一起讨论,我也在看这本书,这本书有一些内容只是点到为止,或许咱们在这里可以讨论一下,相关的更深入的内容Top

11 楼dch4890164(巴拉克)回复于 2006-04-05 15:36:42 得分 0

认真学习!!  
  呵呵  
  原来你是老大啊!!  
   
  Top

12 楼goodboy1881(积木)(谁都别拦着我在水源升星)回复于 2006-04-05 16:04:32 得分 0

csdn要是支持HTML或者是BBCode就好了。Top

13 楼abblly(西边日出东边雨)回复于 2006-04-05 16:51:05 得分 0

斑竹辛苦了,看来译者已经同意你这样做了,继续。Top

14 楼Nickoll(异类铀变)回复于 2006-04-05 17:32:38 得分 0

斑竹,能不能QQ交流下.  
   
  期待中!!!!!!Top

15 楼baggio1984(good good study ,day day up !)回复于 2006-04-05 19:17:33 得分 0

向美女学习Top

16 楼zhejiang9(麻花!大花裤衩!)回复于 2006-04-05 20:20:09 得分 0

我倒!都是色魔啊,看来这个世界只有我最纯洁了!哈哈Top

17 楼cunsh(村少)回复于 2006-04-05 22:27:16 得分 0

mark  
  xuexi;Top

18 楼shenmea00000(学习中~~~)回复于 2006-04-05 23:35:18 得分 0

学习中~~~Top

19 楼junnyfeng(风歌)回复于 2006-04-05 23:45:35 得分 0

这个书上的东西要来干吗Top

20 楼du51(郁郁思扬)回复于 2006-04-06 00:06:37 得分 0

很有用呀.Top

21 楼xlsue(小林)回复于 2006-04-06 00:19:34 得分 0

太太???顶!!!Top

22 楼terryjwf(开大奔的帅哥)回复于 2006-04-06 09:10:57 得分 0

对你的崇拜犹如黄河泛滥滔滔江水连绵不绝。。。Top

23 楼powerbamboo(清风明月)回复于 2006-04-06 09:20:49 得分 0

顶一下Top

24 楼windking21(想玩玩WOW 真的那么难吗)回复于 2006-04-06 09:39:56 得分 0

感觉看的不很透彻Top

25 楼ihyy(花火)回复于 2006-04-06 10:12:45 得分 0

上次看到这本书还犹豫要不要买。现在可以肯定不用买了。天天来看fifty   m   mm的文档了:)  
   
   
  Top

26 楼ovol(冰山)回复于 2006-04-06 19:09:29 得分 0

markTop

27 楼Chulangzi(楚浪子-我要变强!)回复于 2006-04-06 19:56:19 得分 0

哈哈,学习来了哦Top

28 楼lovetsfuer(实践是检验一切的真理!)回复于 2006-04-06 20:52:47 得分 0

什么书?说出来我也学习学习。  
  Top

29 楼qsdnet(我想学编程)回复于 2006-04-06 21:54:03 得分 0

非常感谢楼主分享,如果楼主用Base表示基类,Derived表示派生类就更好明白了,小弟是个菜鸟,请见谅!!!Top

30 楼mymyal123(风之森)回复于 2006-04-06 23:40:04 得分 0

upTop

31 楼sjjf(水晶剑锋)回复于 2006-04-07 01:40:44 得分 0

markTop

32 楼maojun1986(Finality)回复于 2006-04-07 11:37:31 得分 0

教学贴都有。。呵呵!!楼主真细心啊。。我门好好学!!Top

33 楼xuelong_zl(点雨点[我身上咋就没MM的香水味涅??#-_-])回复于 2006-04-11 10:49:57 得分 0

偶是纯来支持的.......Top

34 楼howyougen(夫孝,德之本也,教之所由生也)回复于 2006-04-12 13:01:53 得分 0

荣耀都惊动了!!  
  向荣先生致敬先,50mm也辛苦啦Top

35 楼pacman2000(pacman)(影子传说)回复于 2006-04-12 13:48:00 得分 0

呵呵!   厉害了!!!Top

相关问题

关键词

得分解答快速导航

  • 帖主:fiftymetre

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo