zoukankan      html  css  js  c++  java
  • 读书笔记六

    • 确定你的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 的两辆组合。

      

  • 相关阅读:
    作为一个程序猿,是不是经常会用到.chm文档,但是我们可能会遇到这样那样的问题,比如.chm文档打不开
    总结
    图片轮播的几种方式
    学习中于遇到的问题总结
    node 总结
    webpack 总结
    babel 的总结和理解
    关于css 的AST 语法树的理解
    js中的正则表达式
    八皇后
  • 原文地址:https://www.cnblogs.com/Kobe10/p/5743701.html
Copyright © 2011-2022 走看看