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. 在使用多继承时只从纯虚类派生
     */
    
  • 相关阅读:
    设置matplotlib.pyplot设置画图的坐标系
    [leetcode]238. 除自身以外数组的乘积
    彩色图到灰度图究竟是怎么变换的
    1.1 PIL:Python图像处理类库
    基于GoogLeNet的不同花分类微调训练案例
    消息队列 ActiveMQ的简单了解以及点对点与发布订阅的方法实现ActiveMQ
    解决session共享问题
    linux安装Nginx 以及 keepalived 管理Nginx
    nginx解决服务器宕机、解决跨域问题、配置防盗链、防止DDOS流量攻击
    Nginx实现负载均衡
  • 原文地址:https://www.cnblogs.com/logchen/p/10176786.html
Copyright © 2011-2022 走看看