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

来源:互联网 发布:python 数据分析实战 编辑:程序博客网 时间:2024/05/21 16:17

多重继承

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

class Pegasus : public Horse,public Bird {}

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

/* *Multiple_interitance.cpp *Date : 2013-10-20 *Author: sjin *Mail:413977243@qq.com */#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:1Horse constructor... (1) Horse (2) Pegasus:2Horse constructor... Bird constructor... Pegasus constructor...************************************************* (1) Bird (2) Pegasus:1 Bird constructor... (1) Bird (2) Pegasus:2Horse 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对象的组成部分。如下面所示:


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

/* *Multiple_interitance.cpp *Date : 2013-10-27 *Author: sjin *Mail:413977243@qq.com */#include <iostream>#define N 0using 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();}#endifprivate:    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 10Pegasus height  is 5Pegasus color  is 0 Pegasus destructor...Bird destructor...Horse destructor...

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


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