单继承与多继承与boss菱形继承

单继承

  一个子类只能有一个直接父类称为单继承。简单的一对一关系。
  这里写图片描述

多继承

 1. 一个子类有多个直接父类称为多继承。一对多关系。
  这里写图片描述

class AA
{
public:
    int _a;
};
class BB 
{
public:
    int _a;
    int _b;
};
class CC :public BB,public AA
{
public:
    int _c;
};
void Test1()
{
    CC c;
}

  多继承使一个子类可以继承多个父类的特性,它可以看作是单继承的扩展,它有多个基类,派生类与每个基类间都是一对一的单继承关系。在子类的内存中是按照继承的顺序存放的。但是正因为它可以继承多个父类,所以它引发了两个问题:数据冗余和二义性
  好比上述例子:父类AA 和BB都有成员变量_a,那么子类CC继承后,CC理所应当的也拥有了两个父类的非private成员,那么CC中就存放了两份成员变量_a,那么对象c访问_a时访问的到底是父类AA的还是父类BB的?
  解决办法:
  第一:使用作用域符::
  直接告诉你对象c访问的具体哪一个父类,肯定不会错了。

CC c;
c.AA::_a = 1;

  第二: 虚继承

 2. 多继承的构造函数
   首先要切记一点:构造函数不会被继承! 
   派生类构造函数执行顺序是先执行所属基类的构造函数,再执行派生类本身构造函数,处于同一层次的各基类构造函数的执行顺序取决于定义派生类时所指定的各基类顺序,与派生类构造函数中所定义的成员初始化列表的各项顺序无关。也就是说,执行基类构造函数的顺序取决于定义派生类时基类的顺序。可见,派生类构造函数的成员初始化列表中各项顺序可以任意地排列。就好比上述例子:先调用BB的构造函数,其次是AA的,最后是子类自身。

菱形继承

  有了多继承,必定会有菱形继承,多继承关系中,多个父类又同时继承与一个另一个父类,这就是菱形继承。菱形继承和多继承一样,都可以让子类拥有更多父类的特性,同时菱形继承势必会引发致命问题:数据冗余和二义性。
  这里写图片描述
 上代码镇贴:
 

class Person
{
public :
    string _name ; // 姓名
};
class Student : public Person
{
protected :
    int _num ; //学号
};
class Teacher : public Person
{
protected :
    int _id ; // 职工编号
};
class Assistant : public Student, public Teacher
{
protected :
    string _majorCourse ; // 主修课程
};
void Test ()
{
// 解决二义性方法1:(作用域符)
Assistant a ;
a.Student ::_name = "xxx";
a.Teacher ::_name = "yyy";
}

  子类Assistant继承了两个父类,而两个父类又继承与另一个父类,对于子类Assistant来说,就存在了二义性问题。
  上面用作用域符解决了二义性问题,这里采用虚继承的方法。
  那么何为虚继承?在继承方式前面加上关键字virtual就是虚继承

class AA 
{
public:
    int _a;
};
class BB : virtual public AA//虚继承
{
public:
    int _b;
};
class CC : virtual public AA//虚继承
{
public:
    int _c;
};
class DD : public BB, public CC
{
public:
    int _d;
};

  那么,虚继承是如何解决二义性的呢?
  虚继承让冲突的成员变量只保存一份,也就是共享一份,这样就不会出现二义性问题。
  就好比三个孩子在看一个电视,那么一个孩子换了台,那么其他两个孩子看到的就是换台以后的节目。
  这里写图片描述

  通过虚继承,我们让出现二义性的成员变量只保存了一份,其他对象通过虚基表指针找到这个成员变量,这样就解决了二义性问题。
  同时虚继承也解决了它数据冗余的问题,虽然上述例子内存中添加了两个虚基表指针,让内存大小还变大,比不用虚继承还多了4个字节。但是当基数很大时,虚继承的优势就体现出来了,我只是加了两个虚基表指针,指向共享成员变量位置,不再像以前那样父类的数据我都得继承下来,大大减小了空间的开销。
 

猜你喜欢

转载自blog.csdn.net/CY071512/article/details/80040986