读书笔记六

  • 确定你的public继承塑模出is-a关系

    •   public继承和is-a的之间的等价关系很简单。例如动物和鸟,鸟一定是动物,而动物不一定是鸟。
    •   public继承意味着is-a。适用于base classes身上的每一件事情也是一定适用于派生类身上的,因为每一个派生类对象也都是一个base classes对象。
  • 避免遮掩继承而来的名称
    • int x;//global变量
      void somefunc(){
          double x;//local变量,这个变量会遮掩吊全局变量,在这个函数体内,改变的是double的x。
          cin>>x;
      }
    •   实际上类的继承中也是会发生这样的事情。派生类继承基类,派生类的作用域是嵌套在基类中的。

      class base{
      private:
          int x;
      public:
          virtual void mf1()=0;
          virtual void mf1(int );
          virtual void mf2();
          void mf3();
          void mf3(double);
          ...
      };
      class derived :public base{
      public:
          virtual void mf1();
          void mf3();
          void mf4();
      };
      int main(){
          derived d;
          int x;
          d.mf1();//true    调用derived::mf1
          d.mf1(x);//wrong  derived::mf1遮掩了base::mf1(int)
          d.mf2();//true
          d.mf3();//true
          d.mf3(x);//wrong derived::mf3遮掩了base::mf3(double)
      }
      //这里面的是名称遮掩规则,不考虑参数的类型,而是直接考虑名称,这里直接相关的东西是作用域这个东西。
      //解决办法:在main函数中,明确的使用using声明表达式去显示的调用自己享用的函数即可。
    •   在public继承下,derived类的名称会遮掩base class内的名称。在public继承下面从来没有人希望如此
    •   我们可以使用using声明表达式去显示的调用想调用的函数或者变量等。
  • 区分接口继承和实现继承
    •   一个基类有三个函数:一个pure virtual,一个 impure virtual,一个non virtual。

      •   声明一个pure virtual函数的目的是让片派生类只是继承函数接口
      •   声明一个impure virtual函数的目的是让派生类继承该函数的接口给和缺省实现:继承该非纯虚函数,既可以自己实现这个函数,也可以缺省的调用父类的这个函数而不去重写派生类中的这个函数
      •   声明一个non virtual函数的目的是为了令派生类继承函数的接口给及一份强制性实现。
    •   接口继承和实现继承不同,在public继承下,派生类总是继承base class的接口
    •   pure virtual函数只是具体制定接口继承,impure virtual函数具体指定接口继承和缺省的实现继承,non virtual函数具体制定接口继承以及强制性实现继承
  • 绝对不重新定义继承而来的non-virtual
    •   non-virtual是静态绑定的,virtual是动态绑定的。

      class b{
      public:
          void mf();
      };
      class d:public b{
          void mf();
      };
      int main(){
          d x;
          b* pb=&x;
          pb->mf();
      
          d* pd=&x;
          pd->mf();
      }
      //其中b的mf函数和d的函数mf都是静态绑定的,non-virtual函数。但是如果mf是一个virtual函数的话,那么virtual是动态绑定的,mf是个virtual函数,不论通过pb还是pd
      //调用mf,都会是调用的pd::mf()。
  • 绝不重新定义继承而来的缺省参数值
    •   virtual是动态绑定的(调用一个virtual函数时,究竟调用哪一个实现代码,由调用的那个独享的动态类型),non-virtual是静态绑定的,缺省参数值也是静态绑定的。

      class shape{
      public:
          enum shapecolor{red,green,blue};
          virtual void draw(shapecolor color = red)const=0;//带有默认参数的virtual函数绝对不重新定义该默认参数
          ...
      };
      class rectangle:public shape{
      public:
          virtual void draw(shapecolor color = red)const;//这样就代码重复了
      };
      
      //修改的版本
      class shape{
      public:
          enum shapecolor{red,green,blue};
          void draw(shapecolor color = red)const{
              dodraw(color);
          }
          ...
      private:
          virtual void dodraw(shapecolor color)cosnt = 0;
      };
      class rectangle:public shape{
      public:
          ... ;
      private:
          virtual void dodraw(shapecolor color)const;//这里不需要指定默认参数值
      };
      //这里就是利用了non-virtual函数永远不会被派生类重写,这样就能保证默认参数值不会被修改和重新定义了。
  • 通过复合塑模出has-a或者根据某物实现出
    •   复合:类型之间的一种关系,当某种类型的对象内含它种类型的对象。它意味着has-a或者是is-implement-in-terms-of(根据某物实现出)。当复合发生在应用域内的对象的时候表现出has-a关系,发生在实现域表现is-implement-in-terms-of。

      •   应用域:人,汽车,动物,这些属于应用域。
      •   实现域:像缓冲器,查找树,互斥器这种东西属于实现域。
    •   复用和继承完全不同的,复用不用去继承。
  • 明智而审慎的使用private继承
    •   private意味着;private的派生对象系统是不会自动的将它变成一个base类对象的。从private base class中继承而来的所有成员在derived class都会变成paivate属性。
    •   private意味着:根据某物实现出is-implement-in-terms-of。如果D以private形式继承B,意思是D对象根据B对象实现而得。
    •   由于复合和private继承貌似有重合的部分,但是我们尽可能的使用复合,在必要时才使用private继承。
  • 明智而审慎的使用多重继承
    •   当多重继承出现的时候,程序有可能从一个以上的base class继承相同名称的函数或者其他东西。会产生较多的起义。
    •   多重继承比单一继承复杂,他可能导致新的起义性,以及对virtual继承的需要。
    •   virtual继承会增加大小,速度,初始化复杂度等等成本。如果virtual base class不带任何数据,将是最具实用价值的情况。
    •   多重继承的确有正当用途。其中一个情节设计public继承某个interface class和private继承某个协助实现的class 的两辆组合。

  

时间: 2024-09-30 20:50:49

读书笔记六的相关文章

悟道—位IT高管20年的职场心经(读书笔记六)

悟道--一位IT高管20年的职场心经 第七章  关于销售 用"最"来形容公司的销售,可以用上若干的词汇: 最牛,最累,最精,最傻,最有钱,最贱,最能吹,最能装... 1.1  销售人得基本素质 善胜者不争,善争者不战,善战者不败,善败者不乱. 五勤:嘴勤.腿勤.手勤(勤读勤记).耳目勤(多看多听).脑勤(勤思勤省). 能吃苦:身体之苦,巨大的心理压力. Not too hard, to be smarter! 1.2  销售VS前锋 最重要的是"临门一脚".拿下单子

Android驱动开发读书笔记六

第六章 Linux 驱动的工作和访问方式是 Linux 的亮点之一,Linux 系统将每一个驱动都映射成一个文件.这些文件称为设备文件或驱动文件,都保存在/dev目录中,由于大多数Linux驱动都有与其对应的设备文件,因此与Linux驱动交换数据就变成了与设备文件交换数据.介绍到如何在多种平台,使用多种方式测试Linux驱动.给出的实例是统计单词的个数,但是关键还在实现该算法的技术是Linux 驱动. (一).编写Linux驱动程序的步骤 1.建立Linux驱动骨架(装载和卸载Linux驱动)

《构建之法》读书笔记六

第14章:质量保障 软件的开发过程有三个主要特性:好.快.便宜.在开发一个软件时,我们应该尽可能的保证软件的质量,不能盲目地听从所谓的"专业人士"的意见,要有自己的见解. 衡量一个软件的质量: 研发出符合用户需求的软件 通过一定的软件流程,在预计的时间内发布"足够好"的软件 并通过数据和其他方式展现所开发的软件是可以维护和继续发展的. 第十五章:稳定和发布阶段 1.对bug进行会诊,确定:修复,砍掉,保持 2.事后诸葛亮会议:在开发过程中学到的知识,缺点

Distributed Programming With Ruby》读书笔记六 Starfish, Distribunaut and Politics (Part2 chapter4-6)

Chapter4: Starfish (海星?)这样的例子有时间换linux的环境试一下吧 Starfish1 bills itself as "a utility to make distributed programming ridiculously easy." I think that is a bit of an overstatement, but Starfish certainly can make distributed programming easier. Thi

读书笔记(六)

第一个Linux驱动程序: Linux驱动的工作和访问方式是Linux的亮点之一, 同时受到了业界的广泛好评. Linux系统 将每一个驱动都映射成一个文件.这些文件称为设备文件或驱动文件,都保存在/dev目录中.这种 设计理念使得与Linux驱动进行交互就像与普通文件进行交互一样容易.当然,也比访问LinuxAPI 更容易. 由于大多数Linux驱动都有与其对应的设备文件, 因此与Linux驱动交换数据就变成了与 设备文件交换数据.例如,向Linux打印机驱动发送一个打印命令,可以直接使用C语

CleanCode读书笔记六

类 单一权责(SRP) public class SuperDashboard extends JFrame implements MetaDataUser { public Component getLastFocusedComponent() public void setLastFocused(Component lastFocused) public int getMajorVersionNumber() public int getMinorVersionNumber() public

Machine Learning for hackers读书笔记(六)正则化:文本回归

data<-'F:\\learning\\ML_for_Hackers\\ML_for_Hackers-master\\06-Regularization\\data\\' ranks <- read.csv(file.path(data, 'oreilly.csv'),stringsAsFactors = FALSE) library('tm') documents <- data.frame(Text = ranks$Long.Desc.)row.names(documents) &

这就是搜索引擎--读书笔记六--索引的查询

索引的查询处理 为搜索引擎构建索引,其目的是能更快速地提取与用户查询相关的文档信息,假设搜索引擎已经建立了索引,我们如何利用倒排索引来相应用户的查询呢?这一次的总结就是给大家分享一下搜索引擎对于用户查询的处理过程. 目前有两种常见的查询处理机制,一种称为一次一文档方式,另外一种称为一次一单词方式. 下面我们用一个具体例子来分别说明两种基本查询处理方式的运行机制.在这个例子里,假设用户输入的查询为“搜索引擎 技术”,而“搜索引擎”这个单词对应的倒排列表中,文档ID依次为{1,3,4},“技术”这个

《http权威指南》读书笔记 六

HTTP客户端识别 可以记录客户端信息的http首部:From,User-Agent,Referer,Authorization,Client-IP,X-Forwarded-For,Cookie From:记录客户端的Email地址 User-Agent:记录客户端浏览器信息 Referer:记录用户来源页面的url(用户从哪个页面链接过来的) 用户登录:在浏览器发送请求时,如果服务器希望用户登录,会返回401 Login Required.浏览器会显示一个登录对话框,并用Authorizati