zoukankan      html  css  js  c++  java
  • C++进阶--多继承

    //###########################################################################
    /*
     * 多继承
     *
     *  -- 一个类直接派生自不止一个基类
     *
     *  -- 利弊?
     */
    
    
    //###########################################################################
    /*
     * 多继承
     */
    
    
    class InputFile {
       public:
       void read();
       private:
       void open();
    };
    
    class OutputFile {
       public:
       void write();
       void open();
    };
    
    class IOFile : public InputFile, public OutputFile {
    };
    
    int main() {
       IOFile f;
    }
    
    
    // Notes:
    //   void open();
    //   f.open();    //这里编译不过,即使其中一个是私有函数。因为函数匹配性检查在权限检查之前
    //正确的调用方式:
    //f.Output::open();
    //两者类都存在open函数,改进成如下方式
    
    
    class File {                //         File
       public:                  //         /          -
       string name;        // InputFile  OutputFile
       void open();           //           /
    };                            //        IOFile
    
    class InputFile : virtual public File {
    };                              
                                    
    class OutputFile : virtual public File {
    };                              
    
    class IOFile : public InputFile, public OutputFile {
    };  // 菱形继承
    
    int main() {
       IOFile f;
       f.open();    //但是这样仍然编译不过,open()二义性
       //f.InputFile::name = "File1";  //不仅open有两个,name也有两个
       //f.OutputFile::name = "File2";
    }
    
    
    //解决方式: 虚继承
    //但是引入了一个新问题,基类的初始化用哪个?
    //C++提供了在最终派生指定的一个解决办法
    class File {     
       public:      
       File(string fname);
    };             
    
    class InputFile : virtual public File {
       InputFile(string fname) : File(fname) {}     //这边的File(fname)会被忽略
    };                              
                                    
    class OutputFile : virtual public File {
       OutputFile(string fname) : File(fname) {}    //这边的File(fname)会被忽略
    };                              
    
    class IOFile : public InputFile, public OutputFile {
       IOFile(string fname) : OutputFile(fname), InputFile(fname), File(fname) {} //不管派生类有多远,都要负责初始化虚基类
    };  
    
    int main() {
       IOFile f;
    }
    
    
    // 既然有这些问题,为什么要用多继承?
    /*
     * 接口隔离原则
     * 
     * 将大的接口分割成更小且更专用的接口。从而使用户只需要知道他们感兴趣的方法
     */
    
    //例如,Andy可能总共有500个API,但是如果你只关心他作为工程师的特性,你只需要知道工程师的40个API
    class Engineer {
       public:
       ...; // 40 APIs
    };
    
    class Son {
       public:
       ...; // 50 APIs
    };
    
    ...
    
    class Andy : public Engineer, Son {
       public:
       ...; // 500 APIs
       };
    
    
    /*
     * ISP的好处:
     * 1. 接口易于使用
     * 2. 静态类型安全
     */
    /*
    
    // 那么怎么样在享受多继承的好处的同时,避免前面提到的问题
     *  【纯虚类】
     *
     *  虚类: 有一个或多个纯虚函数的类
     *
     *  纯虚类: 
     *  一个类只包含纯虚函数
     *    - 没有数据
     *    - 没有实体函数
     *    - 没有私有和保护的函数
     */
    
    class OutputFile {
       public:
       void write() = 0; //没有初始化及二义性的问题
       void open() = 0;
    };
    
    
    
    /*
     * 总结:
     * 1. 多继承是一个重要的技术, 即 接口隔离原则
     * 2. 在使用多继承时只从纯虚类派生
     */
    
  • 相关阅读:
    js/jquery键盘事件及keycode大全
    阿里巴巴首款商用字体免费开放:阿里巴巴普惠字体
    从kinit到kerberos安全机制
    react中dangerouslySetInnerHTML使用
    URLSearchParams
    React router的Route中component和render属性的使用
    SSH 命令的三种代理功能(-L/-R/-D)
    H5 直播的疯狂点赞动画是如何实现的?(附完整源码)
    CenterOS中安装Redis及开机启动设置
    使用require.context实现前端自动化
  • 原文地址:https://www.cnblogs.com/logchen/p/10176786.html
Copyright © 2011-2022 走看看