C++ 多重继承

来源:互联网 发布:用单片机实现电子音响 编辑:程序博客网 时间:2024/05/16 07:19

一、单继承存在的问题
   假设你使用Animal类已经有一段时间后,并将类层次结构分为了鸟类和哺乳动物。Bird类包括成员函数fly,从Mammal类派生出了Horse类,Horse类包括成员函数whinny和gallop.
   现在需要一个飞马对象Pegasus:一种介于马和鸟之间的动物。它可能包含成员函数fly和whinny。这是使用单继承就会陷入困境。
   第一种解决方法:从Horse类派生出Pegasus,将fly复制到Pegasus中。这样不得不使维护人员修改fly,需要修改两处地方。但是这种方法,不能将Pegasus解释为一个
   Bird对象。
   第二种方法,将Horse类gallop方法重命名为move,然后在Pegasus中覆盖move使其完成fly工作。如
   Pegasus::move(long distance)
   {
      if(distance > veryFar)
         fly(distance);
       else
        gallop(distance);      
   }
   不足之处就是,当飞马短距离也想飞,这就不好办了。
   第三种方法,提升。将所需的函数放到类层次结构较高的位置。如果公用的方法变多了,基类就非常庞大。
   第三种方法:向下转换。把fly方法留在Pegasus中,仅当指针指向Pegasus对象时才调用它。使用dynamic_cast来检查。
二、多重继承
    语法:
    class DerivedClass : public BaseClass1,public BaseClass2
    在内存中创建DerivedClass时,两个基类都将成为Pegasus对象的组成部分。
    有多个基类需要处理的问题:
    1 如果碰巧两个基类都有同名的虚函数或数据将如何处理?完全限定法
    2 如果调用多个基类构造函数?
    CPegasus(COLOR color, bool migration, HANDS height,int age):
    CHorse(color, height,age),
    CBird(color, migration,age)
    3 如果多个基类都从同一个类派生而来又将如何呢?
    完全限定法pPeg-> CHorse::getColor()
    4 从共同基类继承,如果调用共同基类的方法
    完全限定法CHorse::getAge()

    或者虚继承


三、虚继承
    如果Horse和Bird有相同的基类,决定使用哪个方法,是随意的。不过,可以告诉C++,不想使用共同基类的两个副本,而只是想要一个共同基类的副本。可让Animal成为Horse和Bird的续基类。只需要在声明中添加关键字virtual即可,Animal不用修改。对Pegasus要做大量修改。

      虚继承2                     虚继承1
    通常,类的构造函数只初始化自己的变量及其基类,但虚继承的基类例外,它们由最后的派生类进行初始化。因此,Animal不是由Horse和Bird初始化,而是由Pegasus初始化。Horse和Bird必须在其构造函数初始化Animal,但是创建Pegasus对象时,这些初始化被忽略了。
    class CHorse:virtual public CAnimal
    class CBird:virtual public CAnimal
    CPegasus(COLOR color, bool migration, HANDS height,int age):CHorse(color, height,age),
    CBird(color, migration,age),CAnimal(age*2)

四、多重继承存在的问题
    开发多继承类层次结构比开发单继承层次结构更困难且风险更大,且调试难度较大。诸如Java和C#等语言都不支持多重继承。
五、混合(功能)类   
    在多重继承和单继承之间的一种折中方案是使用混合类(mixin)。混合类增加专用功能而不会增加大量方法或数据的类。
    功能类与其他类的唯一区别是:功能类没有或只有很少的数据。

原创粉丝点击