• 第五十三课、被遗弃的多重继承(上)


    一、c++的多重继承

    1、c++支持编写多重继承的代码

    (1)、一个子类可以拥有多个父类

    (2)、子类拥有所有父类的成员变量

    (3)、子类继承所有父类的成员函数

    (4)、子类对象可以当做任意父类对象使用

    2、多重继承产生的问题一:通过多重继承得到的对象拥有不同的地址

    #include<iostream>
    
    using namespace std;
    
    class BaseA
    {
    protected:    
        int ma;
    public:
        BaseA(int a)
        {
             ma = a;       
        }
    
        int GetA()
        {
            return ma;
        }
    };
    class BaseB
    {
    protected:    
        int mb;
    public:
        BaseB(int b)
        {
            mb = b;       
        }
    
        int GetB()
        {
            return mb;
        }
    };
    
    class Derived : public BaseA, public BaseB
    {
        int mc;
    public:
        Derived(int a, int b, int c) : BaseA(a), BaseB(b)//在初始化列表显示调用构造函数,构造顺序先父母,后他人,再自己
        {
            mc = c;       
        }
    
        int GetC()
        {
            return mc;
        }
    
        void print()
        {
            cout << "ma = " << ma << ","
                 << "mb = " << mb << ","
                  << "ma = " << mc << endl;    
        }
    };
    
    int main()
    {
        cout << "sizeof(Derived) = " << sizeof(Derived) << endl;    // 12
        
        Derived d(1, 2, 3);
        
        d.print();
        
        cout << "d.GetA() = " << d.GetA() << endl;
        cout << "d.GetB() = " << d.GetB() << endl;
        cout << "d.GetC() = " << d.GetC() << endl;
    
        cout << endl;
        
        BaseA* pa = &d;//赋值兼容性
        BaseB* pb = &d;
        
        cout << "pa->GetA() = " << pa->GetA() << endl;
        cout << "pb->GetB() = " << pb->GetB() << endl;
    
    
         cout << endl;
        
        void* paa = pa;
        void* pbb = pb;
        
        
        if( paa == pbb )
        {
            cout << "Pointer to the same object!" << endl; 
        }
        else
        {
            cout << "Error" << endl;//输出这个,说明同一对象拥有不同的地址
        }
        
        cout << "pa = " << pa << endl;
        cout << "pb = " << pb << endl;
        cout << "paa = " << paa << endl;
        cout << "pbb = " << pbb << endl; 
    
    
           
        return 0;
    }
    
    //输出结果
    /*
    sizeof(Derived) = 12
    ma = 1,mb = 2,ma = 3
    d.getA() = 1
    d.getB() = 2
    d.getC() = 3
    
    pa->getA() = 1
    pb->getB() = 2
    
    Error
    pa = 0xbfa104f4//发现地址值相差4,还是指向同一个对象,但是指向同一个对象的不同位置
    pb = 0xbfa104f8
    paa = 0xbfa104f4
    pbb = 0xbfa104f8
    */

    二、多重继承产生的问题二:当多重继承出现闭合时产生冗余的成员

    (1)、虚继承能够解决数据冗余问题

    (2)、中间层父类不再关心顶层父类的初始化

    (3)、最终子类必须直接调用顶层父类的构造函数

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class People
    {
        string m_name;
        int m_age;
    public:
        People(string name, int age)
        {
            m_name = name;
            m_age = age;
        }
        void print()
        {
            cout << "Name = " << m_name << ", "
                 << "Age = " << m_age << endl;
        }
    };
    
    class Teacher : virtual public People//虚继承
    {
    public:
        Teacher(string name, int age) : People(name, age)
        {
        }
    };
    
    class Student : virtual public People//虚继承
    {
    public:
        Student(string name, int age) : People(name, age)
        {
        }
    };
    
    class Doctor : public Teacher, public Student
    {
    public:
        Doctor(string name, int age) : Teacher(name, age), Student(name, age), People(name, age)//最终子类必须直接调用最顶层父类的构造函数
        {
        }
    };
    
    int main()
    {
        Doctor d("Delphi", 33);
        
        d.print();
        
        return 0;
    }

    三、小结

    1、c++支持多继承的编程方式

    2、多继承容易带来问题

    (1)、可能出现同一个对象地址不同的情况

    (2)、虚继承可以解决数据冗余的问题

    (3)、虚继承使得架构设计可能出现问题

  • 相关阅读:
    linux系统编程之(一) 信号量
    linux 工具(1)------终端提示符配置
    网络那点事之socket队列
    磨刀砍柴
    线程的分离链接属性
    error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "stdafx.h"”?
    mkdir和_mkdir的区别
    错误 1 error C4996: 'getcwd': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _getcwd. See online help for details.
    error C4996: 'getcwd': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _getcwd. See online help for details. c:users12968desktop estapp estapp estapp.c
    .net与C#
  • 原文地址:https://www.cnblogs.com/gui-lin/p/6370000.html
Copyright © 2020-2023  润新知