条款42:明智地使用私有继承.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文档。上传文档
查看更多
条款42:明智地使用私有继承

条款42:明智地使用私有继承 条款42: 明智地使用私有继承 条款35说明,C++将公有继承视为 是一个 的关系。它是通过这个例子来证实的:假如某个类层次结构中,Student类从Person类公有继承,为了使某个函数成功调用,编译器可以在必要时隐式地将Student转换为Person。这个例子很值得再看一遍,只是现在,公有继承换成了私有继承: class Person { ... }; class Student: // 这一次我们 private Person { ... }; // 使用私有继承 void dance(const Person p); // 每个人会跳舞 void study(const Student s); // 只有学生才学习 Person p; // p是一个人 Student s; // s是一个学生 dance(p); // 正确, p是一个人 dance(s); // 错误!一个学生不是一个人 很显然,私有继承的含义不是 是一个,那它的含义是什么呢? 别忙! 你说。在弄清含义之前,让我们先看看行为。私有继承有那些行为特征呢? 那好吧。关于私有继承的第一个规则正如你现在所看到的:和公有继承相反,如果两个类之间的继承关系为私有,编译器一般不会将派生类对象(如Student)转换成基类对象(如Person)。这就是上面的代码中为对象s调用dance会失败的原因。第二个规则是,从私有基类继承而来的成员都成为了派生类的私有成员,即使它们在基类中是保护或公有成员。行为特征就这些。 这为我们引出了私有继承的含义:私有继承意味着 用...来实现。如果使类D私有继承于类B,这样做是因为你想利用类B中已经存在的某些代码,而不是因为类型B的对象和类型D的对象之间有什么概念上的关系。因而,私有继承纯粹是一种实现技术。用条款36引入的术语来说,私有继承意味着只是继承实现,接口会被忽略。如果D私有继承于B,就是说D对象在实现中用到了B对象,仅此而已。私有继承在软件 设计 过程中毫无意义,只是在软件 实现 时才有用。 私有继承意味着 用...来实现 这一事实会给程序员带来一点混淆,因为条款40指出,分层 也具有相同的含义。怎么在二者之间进行选择呢?答案很简单:尽可能地使用分层,必须时才使用私有继承。什么时候必须呢?这往往是指有保护成员和/或虚函数介入的时候 ---- 但这个问题过一会儿再深入讨论。 条款41提供了一种方法来写一个Stack 模板,此模板生成的类保存不同类型的对象。你应该熟悉一下那个条款。模板是C++最有用的组成部分之一,但一旦开始经常性地使用它,你会发现,如果实例化一个模板一百次,你就可能实例化了那个模板的代码一百次。例如Stack模板,构成Stackint成员函数的代码和构成Stackdouble成员函数的代码是完全分开的。有时这是不可避免的,但即使模板函数实际上可以共享代码,这种代码重复还是可能存在。这种目标代码体积的增加有一个名字:模板导致的 代码膨胀。这不是件好事。 对于某些类,可以采用通用指针来避免它。采用这种方法的类存储的是指针,而不是对象,实现起来就是: · 创建一个类,它存储的是对象的void*指针。 · 创建另外一组类,其唯一目的是用来保证类型安全。这些类都借助第一步中的通用类来完成实际工作。 下面的例子使用了条款41中的非模板Stack类,不同的是这里存储的是通用指针,而不是对象: class GenericStack { public: GenericStack(); ~GenericStack(); void push(void *object); void * pop(); bool empty() const; private: struct StackNode { void *data; // 节点数据 StackNode *next; // 下一节点 StackNode(void *newData, StackNode *nextNode) : data(newData), next(nextNode) {} }; StackNode *top; // 栈顶 GenericStack(const Ge

文档评论(0)

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

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

1亿VIP精品文档

相关文档