Ⅳ 继承与派生②

4.类型兼容

4.1 定义

公有派生的情况下,一个派生类对象可作为基类的对象来使用

◼ 派生类对象可以赋值给基类对象

◼ 派生类对象可以初始化基类的引用

 ◼ 派生类对象的地址可赋给指向基类的指针

 

 5. 多继承类

5.1 定义

#include <iostream>

using namespace std;

class CTopBase
{
protected:
    int a;
public:
    CTopBase(int _a=0)
    {
        a=_a;
        cout << "Top base" << a << endl;
    }

};

class CBase1:public CTopBase
{
    int b;
public:
    CBase1(int _a=0,int _b=0):CTopBase(_a)
    {
        b=_b;
        cout << "Base1" << b << endl;
    }
};

class CBase2:public CTopBase
{
    int c;
public:
    CBase2(int _a=0,int _c=0):CTopBase(_a)
    {
        c=_c;
        cout << "Base2" << c << endl;
    }
};

class CDerived:public CBase1,public CBase2
{
public:
    CDerived(int _a=0,int _c=0,int _b=0):CBase1(_a,_b),CBase2(_a,_c)
    {
        cout << "derived" << endl;
    }
};


int main()
{
    CDerived obj(3,4,5);
    return 0;
}

 问题:顶级基类的构造函数会调用两次 

 5.2 构造与析构函数的调用顺序

◼ 调用各基类构造函数:调用顺序按基类被继承时声明的顺序,从左向右依次进行

◼ 调用派生类成员对象构造函数:调用顺序按其在类中定义的顺序依次执行

◼ 调用派生类构造函数

5.3 二义性

在上面的代码中,如果CBase1和CBase2中都有show()函数,Derived调用的时候就不知道是哪个

(request for member ‘show’ is ambiguous) 

◼ 派生类的多个基类中拥有同名成员时,继承后通过对象调用同名成员将出现二义性

 

6.虚基类

 6.1 定义

class 派生类名:virtual 继承方式 基类名

class CBase1: virtual public CTopBase

class CBase2: virtual public CTopBase

6.2 作用

虚基类构造函数只被调用一次:上面的结果是

 调用一次,但结果为0(默认无参的构造函数),说明CTopBase函数不会被激活

手动更改,给参数:CDerived(int _a=0,int _c=0,int _b=0):CTopBase(_a),CBase1(_a,_b),CBase2(_a,_c)

 ◼ 在派生类建立对象时,先调用基类的构造函数,再调用派生类的构造函数

◼ 类型兼容是指在公有派生的情况下,一个派生类对象可以作为基类的对象来使用

◼ 多继承时,多个基类中的同名成员在派生类中由于标识符不唯一而出现二义性

◼ 在多继承中,当派生类的部分或全部直接基类又是从另一个共同基类派生而来时, 可能会出现间接二义性 → 虚基类

#include <iostream>
#include <windows.h>
#include <mmsystem.h>

using namespace std;

class CAnimal         //基类
{
    string name;
    int age;
    int weight;
public:
    CAnimal(string strName="", int a=0, int w=0)
    {
        name = strName;
        age = a;
        weight = w;
        cout << "Animal constructor " << name << endl;
    }
    void Show()
    {
        cout << name << " " << age << " " << weight << endl;
    }
    ~CAnimal()
    {
        cout << "Animal destructor " << name << endl;
    }
};

class CBird: virtual public CAnimal   //派生类1
{
    int wingSpan;
public:
    CBird(int ws=0, string strName="", int a=0, int w=0):CAnimal(strName, a, w)
    {
        wingSpan = ws;
        cout << "Bird constructor " << endl;
    }
    void Show()
    {
        CAnimal::Show();
        cout << "Wingspan:" << wingSpan << endl;
    }
    void Fly()
    {
        cout << "I can fly! I can fly!!" << endl;
    }
    void Talk()
    {
        cout << "Chirp..." << endl;
        PlaySound(".\sound\eagle.wav",NULL, SND_FILENAME|SND_SYNC);
    }
    ~CBird()
    {
        cout << "Bird destructor " << endl;
    }
};

class CHorse: virtual public CAnimal   //派生类2
{
    int power;
public:
    CHorse(int pow=0, string strName="", int a=0, int w=0):CAnimal(strName, a, w)
    {
        power = pow;
        cout << "Horse constructor " << endl;
    }
    void Show()
    {
        CAnimal::Show();
        cout << "Power:" << power << endl;
    }
    void Run()
    {
        cout << "I can run! I run because I love to!!" << endl;  //emmm
    }
    void Talk()
    {
        cout << "Whinny!..." << endl;
        PlaySound(".\sound\horse.wav",NULL, SND_FILENAME|SND_SYNC);
    }
    ~CHorse()
    {
        cout << "Horse destructor "  << endl;
    }
};

class CPegasus: public CHorse, public CBird  //派生类1&2,无virtual了
{
public:
    CPegasus(string strName="", int a=0, int w=0, int ws=0, int pow=0)
    : CAnimal(strName, a, w), CHorse(pow, strName, a, w), CBird(ws, strName, a, w)
    {
        cout << "Pegasus constructor" << endl;
    }
    void Talk()    {        CBird::Talk();       }
    void Show()    {        CBird::Show();        CHorse::Show();    }
    ~CPegasus()    {        cout << "Pegasus destructor" << endl;    }
};int main()
{
    //CBird birdObj(2, "Eagle", 5, 50);
    //CHorse horObj(10000, "Mogolia horse", 5, 1000);
    //CBull bullObj(20000, "Africa ox", 3, 2000);
    CPegasus pegObj("Pegasus", 5, 5000, 4, 100000);

    pegObj.Talk();   //会发出声音的

    return 0;
}
原文地址:https://www.cnblogs.com/syzyaa/p/12711141.html