zoukankan      html  css  js  c++  java
  • C++_代码重用4-多重继承

    继承使用时要注意,默认是私有派生。所以要公有派生时必须记得加关键字Public。

    MI(Multi Inheritance)会带来哪些问题?以及如何解决它们?

    两个主要问题:

           从两个不同的基类继承同名方法;

           从两个或更多相关基类那里继承同一个类的多个实例;

    虚方法

    Worker公有派生出Singer和Waiter;

    然后Singer和Waiter公有派生出SingingWaiter(即多重继承);

    这样会导致一个问题,就是SingingWaiter中有两个Worker组件。通常可以将派生类对象的地址赋值给基类指针。但是在这样的情况下这么做的话,将出现二义性。所以必须使用类型转换来指定对象。但这又增加了指针引用的复杂度。

           C++在引入多重继承的同时,也引入新技术——虚基类,来解决该问题。

    虚基类也用关键字virtual,虚基类与虚函数之间并不存在明显的联系。这么做是为了给程序员减少压力,类似于关键字的重载。

    class Singer: virtual public Worker{…};

    class Waiter: public virtual Worker{…};

    (virtual和public的次序无关紧要)

     

    那么为什么不使虚行为成为MI的默认准则呢?

           在一些情况下,可能需要基类的多个拷贝;

           将基类作为虚的要求程序完成额外的计算,为不需要的程序付出代价是不应当的;

     

    新的构造函数规则

           使用虚基类时,必须对构造函数采用新的方法;

           对于非虚基类,唯一可以出现在初始化列表中的构造函数是即时基类构造函数。

    A派生B,B派生C;--->C类的构造函数只能调用B类的构造函数,B类的构造函数只能调用A类构造函数。

    但对于虚基类而言,这种信息自动传递方式不可用。这是因为对于多重继承而言,信息传递将通过两条不同的途径。为避免这种冲突,当基类是虚的,将禁止信息通过中间类自动传递给基类。

           这就要求显式地调用所需的基类构造函数:

    SingingWaiter(参数列表):Worker(wk),Waiter(wk,p),Singer(wk,v) { }

    上述格式对虚基类来说是合法的,对非虚基类来说是非法的。

     

    哪个方法

    对于多重继承,如果每个祖先都有一个Show函数,那么会导致函数调用的二义性

    对于单继承,如果没有重新定义show,将调用最近祖先中的show定义。

     

    有几种解决方法:

    1使用作用域解析运算符来澄清编程者的意图;

    2或是在多重继承的类中重新定义show方法,并指出要使用哪个show;

           这种递增的方法对于单继承来说是有效的;

           但是对于多重继承来说,还是有问题:

                  SingingWaiter::Show

                  {Singer::Show();Waiter::Show();} //这将显示姓名和ID两次。

           该如何解决呢?->使用模块化方法,而不是递增的方法;即提供一个只显示worker组件的方法,提供一个只显示waiter组件及singer组件的方法。

     

    将所有数据组件都设置为保护的方法,而不是私有的,可以更严格地控制对数据的访问;

           如果数据组件的方法是保护的,则只能在继承层次结构中的类中使用它,在其他地方则不能使用。

     

    MI小结

           MI会增加编程的复杂度。然而,这种复杂度主要是由于派生类通过多条途径继承同一个基类引起的。

           当派生类使用关键字virtual来指示派生时,基类就称为了虚基类。其构造函数的规则有所变化,不会自动进行信息不换传递,需要显式地调用基类构造函数。

           通过优先规则解决名称二义性。如果一个类从两个不同的类那里继承了两个同名的成员,则需要在派生类中使用类限定符来区分它们。否则,编译器将指出二义性。

           有间接虚基类的派生类包含直接调用间接基类构造函数的构造函数,这对于间接非虚基类来说是非法的。

  • 相关阅读:
    威尔逊置信区间
    mysql函数
    python操作mysql之pymysql
    oracle 表分区
    Python连接sqlserver数据库之pymssql
    python-subprocess
    python-shutil
    python+logging
    公钥加密-DES-RSA
    python-Web-flask-蓝图和单元测试
  • 原文地址:https://www.cnblogs.com/grooovvve/p/10422244.html
Copyright © 2011-2022 走看看