C++ 多重继承

一、单继承存在的问题
   假设你使用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()

    或者虚继承

#include <iostream> #include <string> using namespace std; typedef int HANDS; enum COLOR {Red, Green, Blue, Yellow, White, Black, Brown}; class CAnimal { public: CAnimal(int age){itsAge = age;cout<< "animal constructor" <<endl;} virtual ~CAnimal(){cout<< "animal destructor" <<endl;} virtual void setAge(int age){itsAge = age;} virtual int getAge() const{return itsAge;} private: int itsAge; }; class CHorse:public CAnimal { public: CHorse(COLOR color, HANDS height, int age):CAnimal(age) {itsColor = color;itsHeight= height; cout<< "horse constructor" <<endl;} virtual void whinny() const {cout<< "horse whinny..." <<endl;} virtual ~CHorse(){cout<< "horse destructor" <<endl;} virtual HANDS getHeight() const{return itsHeight;} virtual COLOR getColor() const{return itsColor;} private: COLOR itsColor; HANDS itsHeight; }; class CBird:public CAnimal { public: CBird(COLOR color, bool migration, int age):CAnimal(age) {itsColor = color;itsMigration = migration; cout<< "bird constructor" <<endl;} virtual ~CBird(){cout<< "bird destructor" <<endl;} virtual void chirp() const {cout<< "bird chirp..." <<endl;} virtual void fly() const {cout<< "bird fly..." <<endl;} virtual bool getMigration() const{return itsMigration;} virtual COLOR getColor() const{return itsColor;} private: COLOR itsColor; bool itsMigration; }; class CPegasus:public CHorse, public CBird { public: CPegasus(COLOR color, bool migration, HANDS height,int age):CHorse(color, height,age), CBird(color, migration,age) {cout<< "pegasus constructor" <<endl;} virtual ~CPegasus(){cout<< "pegasus destructor" <<endl;} virtual void chirp() const {whinny();} virtual void fly() const {cout<< "pegasus fly..." <<endl;} //virtual COLOR getColor() const{return CHorse::getColor();} virtual int getAge() const{return CHorse::getAge();} }; int main() { CPegasus *pPeg = new CPegasus(Red, true,5, 10); cout<<" this pegasus's color is " <<pPeg-> CHorse::getColor()<<endl; cout<<" this pegasus's age is " <<pPeg->getAge()<<endl; delete pPeg; return 0; }
三、虚继承
    如果Horse和Bird有相同的基类,决定使用哪个方法,是随意的。不过,可以告诉C++,不想使用共同基类的两个副本,而只是想要一个共同基类的副本。可让Animal成为Horse和Bird的续基类。只需要在声明中添加关键字virtual即可,Animal不用修改。对Pegasus要做大量修改。

      C++ 多重继承_第1张图片                      C++ 多重继承_第2张图片
    通常,类的构造函数只初始化自己的变量及其基类,但虚继承的基类例外,它们由最后的派生类进行初始化。因此,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)

#include <iostream> #include <string> using namespace std; typedef int HANDS; enum COLOR {Red, Green, Blue, Yellow, White, Black, Brown}; class CAnimal { public: CAnimal(int age){itsAge = age;cout<< "animal constructor" <<endl;} virtual ~CAnimal(){cout<< "animal destructor" <<endl;} virtual void setAge(int age){itsAge = age;} virtual int getAge() const{return itsAge;} private: int itsAge; }; /////////////////////////////////// class CHorse:virtual public CAnimal { public: CHorse(COLOR color, HANDS height, int age):CAnimal(age) {itsColor = color;itsHeight= height; cout<< "horse constructor" <<endl;} virtual void whinny() const {cout<< "horse whinny..." <<endl;} virtual ~CHorse(){cout<< "horse destructor" <<endl;} virtual HANDS getHeight() const{return itsHeight;} virtual COLOR getColor() const{return itsColor;} private: COLOR itsColor; HANDS itsHeight; }; /////////////////////////////////// class CBird:virtual public CAnimal { public: CBird(COLOR color, bool migration, int age):CAnimal(age) {itsColor = color;itsMigration = migration; cout<< "bird constructor" <<endl;} virtual ~CBird(){cout<< "bird destructor" <<endl;} virtual void chirp() const {cout<< "bird chirp..." <<endl;} virtual void fly() const {cout<< "bird fly..." <<endl;} virtual bool getMigration() const{return itsMigration;} virtual COLOR getColor() const{return itsColor;} private: COLOR itsColor; bool itsMigration; }; class CPegasus:public CHorse, public CBird { public: /////////////////////////////////// CPegasus(COLOR color, bool migration, HANDS height,int age):CHorse(color, height,age), CBird(color, migration,age),CAnimal(age*2) {cout<< "pegasus constructor" <<endl;} virtual ~CPegasus(){cout<< "pegasus destructor" <<endl;} virtual void chirp() const {whinny();} virtual void fly() const {cout<< "pegasus fly..." <<endl;} //virtual COLOR getColor() const{return CHorse::getColor();} // virtual int getAge() const{return CHorse::getAge();} }; int main() { CPegasus *pPeg = new CPegasus(Red, true,5, 10); cout<<" this pegasus's color is " <<pPeg-> CHorse::getColor()<<endl; cout<<" this pegasus's age is " <<pPeg->getAge()<<endl; delete pPeg; return 0; }

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

你可能感兴趣的:(C++,Class,Constructor,migration,destructor,distance)