条款36:区分接口继承及实现继承.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
条款36:区分接口继承及实现继承

条款36:区分接口继承及实现继承 条款36: 区分接口继承和实现继承 (公有)继承的概念看起来很简单,进一步分析,会发现它由两个可分的部分组成:函数接口的继承和函数实现的继承。这两种继承类型的区别和本书简介中所讨论的函数声明和函数定义间的区别是完全一致的。 作为类的设计者,有时希望派生类只继承成员函数的接口(声明);有时希望派生类同时继承函数的接口和实现,但允许派生类改写实现;有时则希望同时继承接口和实现,并且不允许派生类改写任何东西。 为了更好地体会这些选择间的区别,看下面这个类层次结构,它用来表示一个图形程序中的几何形状: class Shape { public: virtual void draw() const = 0; virtual void error(const string msg); int objectID() const; ... }; class Rectangle: public Shape { ... }; class Ellipse: public Shape { ... }; 纯虚函数draw使得Shape成为一个抽象类。所以,用户不能创建Shape类的实例,只能创建它的派生类的实例。但是,从Shape(公有)继承而来的所有类都受到Shape的巨大影响,因为: · 成员函数的接口总会被继承。正如条款35所说明的,公有继承的含义是 是一个 ,所以对基类成立的所有事实也必须对派生类成立。因此,如果一个函数适用于某个类,也必将适用于它的子类。 Shape类中声明了三个函数。第一个函数,draw,在某一画面上绘制当前对象。第二个函数,error,被其它成员函数调用,用于报告出错信息。第三个函数,objectID,返回当前对象的一个唯一整数标识符(条款17给出了一个怎样使用这种函数的例子)。每个函数以不同的方式声明:draw是一个纯虚函数;error是一个简单的(非纯?)虚函数;objectID是一个非虚函数。这些不同的声明各有什么含义呢? 首先看纯虚函数draw。纯虚函数最显著的特征是:它们必须在继承了它们的任何具体类中重新声明,而且它们在抽象类中往往没有定义。把这两个特征放在一起,就会认识到: · 定义纯虚函数的目的在于,使派生类仅仅只是继承函数的接口。 这对Shape::draw函数来说非常有意义,因为,让所有Shape对象都可以被绘制是很合理,但Shape类无法为Shape::draw提供一个合理的缺省实现。例如,绘制椭园的算法就和绘制矩形的算法大不一样。打个比方来说,上面Shape::draw的声明就象是在告诉子类的设计者,你必须提供一个draw函数,但我不知道你会怎样实现它。 顺便说一句,为一个纯虚函数提供定义也是可能的。也就是说,你可以为Shape::draw提供实现,C++编译器也不会阻拦,但调用它的唯一方式是通过类名完整地指明是哪个调用: Shape *ps = new Shape; // 错误! Shape是抽象的 Shape *ps1 = new Rectangle; // 正确 ps1-draw(); // 调用Rectangle::draw Shape *ps2 = new Ellipse; // 正确 ps2-draw(); // 调用Ellipse::draw ps1-Shape::draw(); // 调用Shape::draw ps2-Shape::draw(); // 调用Shape::draw 一般来说,除了能让你在鸡尾酒会上给你的程序员同行留下深刻印象外,了解这种用法一般没大的作用。然而,正如后面将看到的,它可以被应用为一种机制,为简单的(非纯)虚函数提供 比一般做法更安全 的缺省实现。 有时,声明一个除纯虚函数外什么也不包含的类很有用。这样的类叫协议类(Protocol class),它为派生类仅提供函数接口,完全没有实现。协议类在条款34中介绍过,并将在条款43再次提及。 简单虚函数的情况和纯虚函数有点不一样。照例,派生类继承了函数的接口,但简单虚函数一般还提供了实现,派生类可以选择改写它们或不改写它们。思考片刻就可以认识到: · 声明简单虚函数的目的在于,使派生类继承函数的接口和缺省实现。 具体到Shape::error,这个接口是在说,每个类必须提供一个出错时可以被调用的函数,但每个类可以按它们认为合适的任何方式处理错误。如果某个类不想做什么特别的事,可以借助于Shape类中提供的缺省出错处理函数。也就是说,Shape::error的声明是在告诉子类的设计者,你必须

文档评论(0)

f8r9t5c + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

版权声明书
用户编号:8000054077000003

1亿VIP精品文档

相关文档