zoukankan      html  css  js  c++  java
  • Ⅳ 继承与派生②

    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;
    }
  • 相关阅读:
    Windows 10 Universal App 开发记录
    Windows Phone 8.1 开发会用到的方法
    Android Activity设置全屏
    Android视频录制命令screenrecord
    Android ScrollView中嵌套ListView只显示一行的解决办法
    Android 4.4.4: java.lang.SecurityException: Package com.android.settings does not belong to 1001
    自定义Android spinner样式并添加监听事件
    GSON快速实现内部类
    android的Banner轮播图框架
    Okhttp与Okhttputils的用法及区别
  • 原文地址:https://www.cnblogs.com/syzyaa/p/12711141.html
Copyright © 2011-2022 走看看