zoukankan      html  css  js  c++  java
  • 条款40:慎重的选择多重继承

    多重继承很容易带来的一个问题就是歧义的问题:

     1 class BorrowAble{
     2 public:
     3     void checkOut() const;
     4     ...
     5 };
     6 class ElectronicGadget{
     7 private:
     8     bool checkOut()const;
     9     ...
    10 };
    11 class MP3Player:
    12     public BorrowAbleItem,
    13     public ElectronicGadget
    14     {...};
    15 MP3Player mp;
    16 mp.checkOut();
    这样checkOut的调用实际上就是未定义的了,不考虑作用域来说,这个mp能够取得两个checkOut的名称。
    可能的调用方法就是:mp.BorrowableItem::checkOut();
     
    还有一种致命的问题就是:如果两个base类还拥有一个相同的基类的话,那么就会导致base对象的重复发生。正确的做法是像下面这样使用virtual继承,这样就避免了继承相同的数据:
    1 class File{...};
    2 class InputFile : virtual public File{...};
    3 class OutputFile : virtual public File{...};
    4 class IOFile : public InputFile,
    5                 public OutputFile
    6                 {...};
    当然,使用virtual继承是要付出代价的,起生成的对象往往会更大以及访问速度也会变慢。
     
    另外一个不太显著的缺点是,通过virtual继承得到的最终类往往与其含有数据的基类距离不止一个的继承距离。但是这些类同时还要负责这些佛如初始化工作。
     
    所以综上所述:对于virtual base class 的忠告是很简单的:非必须不要使用virtual base, 如果要使用尽量不要再virtual base中存放数据,以免忘了进行初始化工作之后带来一些诡异的后果。
     
    小结:
    多重继承比单一继承要复杂,可能会导致新的歧义性,以及起往往还需要virtual继承
    virtual继承会增加,大小,速度,初始化,复杂度等成本,最好的virtual base class不应该带有数据。
    多重继承的正确用途往往出现在:
    pubic继承自某个interface class以及private 继承字某个协助实现的class二者的组合。
  • 相关阅读:
    JSON 字符串 与 java 对象的转换
    DNS解析过程详解
    全面了解移动端DNS域名劫持等杂症:原理、根源、HttpDNS解决方案等
    TCP Send函数的阻塞和非阻塞,以及TCP发送数据的异常情况
    基于TCP协议的应用层的ACK机制
    Golang的反射reflect深入理解和示例
    C/C++中struct中内存对齐规则
    Go 包依赖管理工具 —— govendor
    什么是幂等?什么情况下需要考虑幂等?怎么解决幂等的问题?
    Golang 中间件简介 MiddleWare
  • 原文地址:https://www.cnblogs.com/-wang-cheng/p/4889798.html
Copyright © 2011-2022 走看看