走进C++程序世界------多重继承

多重继承

   多重继承:从多个基类派生出来的新类。要从多个基类派生,在类声明中,基类之间用逗号隔开。如下:

class Pegasus : public Horse,public Bird {}

可以看下面的代码,说明了如何声明Pegasus,使其从Horse和Birds派生而来。

/*
 *Multiple_interitance.cpp
 *Date : 2013-10-20
 *Author: sjin
 *Mail:[email protected]
 */
#include <iostream>
using namespace std;

/*声明Horse 类*/
class Horse {
public:
    Horse() { cout << "Horse constructor..." << endl;}
    virtual ~Horse() { cout << "Horse destructor..." << endl;}
    virtual void whinny() const { cout << "whinny!..." << endl;}
private:
    int itsAge;
};

/*声明Bird类*/
class Bird {
public:
    Bird() { cout << " Bird constructor..." << endl; }
    virtual ~Bird() { cout << "Bird destructor..." << endl; }
    virtual void Chirp() const { cout << "Chirp!..."<< endl; }
    virtual void Fly() const { 
        cout << " I can Fly! I can Fly!..."<<endl ;
    }
private:
    int itsWeight;
};

/*使用多重继承声明了Pegasus类*/
class Pegasus : public Horse,public Bird {
public:
    void Chirp() const {
        whinny();
    }
    Pegasus() {cout << " Pegasus constructor..." << endl ;}
    ~Pegasus() { cout << " Pegasus destructor..." << endl ;}
};

/*help*/

void help(int * choice,int flag)
{
    if(flag == 1){
        cout << " (1) Horse (2) Pegasus:";
    }else {
        cout << " (1) Bird (2) Pegasus:";
    }
        
    cin >> *choice;
}

/*分割线*/
void halving_line()
{
    cout << "*************************************************" << endl;
}

const int MagicNumber = 2;

int main()
{
    // Ranch:牧场;Aviary:鸟舍
    Horse *Ranch[MagicNumber];
    Bird * Aviary[MagicNumber];

    Horse * pHorse;
    Bird * pBird;

    int choice,i;
    halving_line();
    for(i = 0; i<MagicNumber; i++){
         help(&choice, 1);
         if(choice == 2){
             pHorse = new Pegasus;
         }else{
             pHorse = new Horse;
         }

         Ranch[i] = pHorse;
    }
    halving_line();
    for(i = 0; i < MagicNumber; i++){
        help(&choice,2);
        if(choice == 2){
            pBird = new Pegasus;
        }else{
            pBird = new Bird;
        }
        Aviary[i] = pBird;
    }
    halving_line();

    for(i = 0;i < MagicNumber; i ++){
        cout << "牧场:" << endl;
        Ranch[i]->whinny();
        delete Ranch[i];
    }


    for(i = 0;i < MagicNumber; i ++){
        cout << "鸟舍:" << endl;
        Aviary[i]->Chirp();
        Aviary[i]->Fly();
        delete Aviary[i];
    }

    return 0;
}

输出:
(1) Horse (2) Pegasus:1
Horse constructor...
 (1) Horse (2) Pegasus:2
Horse constructor...
 Bird constructor...
 Pegasus constructor...
*************************************************
 (1) Bird (2) Pegasus:1
 Bird constructor...
 (1) Bird (2) Pegasus:2
Horse constructor...
 Bird constructor...
 Pegasus constructor...
*************************************************
牧场:
whinny!...
Horse destructor...
牧场:
whinny!...
 Pegasus destructor...
Bird destructor...
Horse destructor...
鸟舍:
Chirp!...
 I can Fly! I can Fly!...
Bird destructor...
鸟舍:
whinny!...
 I can Fly! I can Fly!...
 Pegasus destructor...
Bird destructor...
Horse destructor...

通过输出表名,酶促创建Pegasus对象时都会创建了其Bird部分和Horse部分,当Pegasus对象销毁时,其Bird部分和Horse部分也被销毁。

多种继承对象在内存的分配状况

在内存中创建Pegasus对象时,两个基类都将成为Pegasus对象的组成部分。如下面所示:

走进C++程序世界------多重继承_第1张图片

多重继承中对象中的构造函数:

/*
 *Multiple_interitance.cpp
 *Date : 2013-10-27
 *Author: sjin
 *Mail:[email protected]
 */
#include <iostream>

#define N 0
using namespace std;

/*1、使用重载基类构造函数
 *2、避免歧义
 *
 */

typedef int HANDS;
enum COLOR{
    red,
    green,
    blue,
    yellow,
    white,
    black,
    brown
};



/*声明Horse 类*/
class Horse {
public:
    Horse(COLOR color,HANDS height):itsColor(color),itsWeight(height) { cout << "Horse constructor..." << endl;}
    virtual ~Horse() { cout << "Horse destructor..." << endl;}
    virtual void whinny() const { cout << "whinny!..." << endl;}
    virtual HANDS GetHeight() const {return itsWeight;}
    virtual COLOR GetColor() const {return itsColor;}
private:
    HANDS itsWeight;
    COLOR itsColor;
};

/*声明Bird类*/
class Bird {
public:
    Bird(COLOR color,HANDS height):itsColor(color),itsWeight(height) { cout << " Bird constructor..." << endl; }
    virtual ~Bird() { cout << "Bird destructor..." << endl; }
    virtual void Chirp() const { cout << "Chirp!..."<< endl; }
    virtual void Fly() const { 
        cout << " I can Fly! I can Fly!..."<<endl ;
    }
    virtual HANDS GetHeight() const {return itsWeight;}
    virtual COLOR GetColor() const { return itsColor;}
private:
    HANDS itsWeight;
    COLOR itsColor;
};

/*使用多重继承声明了Pegasus类*/
class Pegasus : public Horse,public Bird {
public:
    void Chirp() const {
        whinny();
    }
    Pegasus(COLOR color,HANDS wight,long numbelieve);
    ~Pegasus() { cout << " Pegasus destructor..." << endl ;}
    virtual long GetNumberBelievers() const {return itsNumberBelievers;}
#if N
    /*下面是另一种方法避免歧义 虚函数*/
    HANDS GetHeight()const {  return Bird::GetHeight();}
    COLOR GetColor()const { return Horse::GetColor();}
#endif

private:
    long itsNumberBelievers;
};

/*Pegasus 构造函数定义*/
Pegasus::Pegasus(COLOR color,HANDS wight,long numbelieve):Horse(color,wight),Bird(color,wight),itsNumberBelievers(numbelieve)
{
    cout << "Pegasus constructor..."<<endl;
}



/*分割线*/
void halving_line()
{
    cout << "*************************************************" << endl;
}


int main()
{
    Pegasus *pPeg = new Pegasus(red,5,10);
    pPeg->Fly();
    pPeg->whinny();

    cout << "Pegasus numbelieve  is " << pPeg->GetNumberBelievers() << endl;
#if  N
    cout << "Pegasus height  is " << pPeg->GetHeight() << endl;
    cout << "Pegasus color is " << pPeg->GetColor() << endl;
#else
/*上面2个打开,会发生多重歧义情况,因为在BirD,和HOrse 都带有2个函数的定义
 * 这个直接使用的话,程序不知道啊 会调用哪个。发生多重歧义
 *请参照下面的下法
 * */
   
    cout << "Pegasus height  is " << pPeg->Bird::GetHeight() << endl;
    cout << "Pegasus color  is " << pPeg->Horse::GetColor() << endl;
#endif

    delete pPeg;
    return 0;

}



输出:
Horse constructor...
 Bird constructor...
Pegasus constructor...
 I can Fly! I can Fly!...
whinny!...
Pegasus numbelieve  is 10
Pegasus height  is 5
Pegasus color  is 0
 Pegasus destructor...
Bird destructor...
Horse destructor...

避免多重歧义:
上面代码中介绍了2种关于避免多重歧义的方法。另外一种方法就是,在派生类中重写响应的函数,覆盖基类的方法。一种是在调用时指定使用那个类的函数。其实2者之间基本思路都是一样的。下面介绍另外一种思路。Brid和Horse有个共同的基类Animal,Animal包含了BIRD和Horse共同的属性。如下图:
走进C++程序世界------多重继承_第2张图片

按照上图,可以看到Bird和Horse是从同一个基类Animal派生而来的。这样实例化Pagasus对象后,也存在歧义的情况,到底是调用Horse还是Bird哪里继承来的color。
所以也会想上面的代码那么麻烦需要指定调用哪个基类的函数。


 

你可能感兴趣的:(多重继承)