继承语法
class 子类: 继承方式 父类 {};
其中继承方式包括:
-
共有继承
-
保护继承
-
私有继承
共有继承
父类中的属性被继承到子类中,并且属性的访问权限也不变,其中父类中的私有成员也被继承下去了,但是不能通过子类访问到,会被编译器隐藏
保护继承
父类中的属性被继承到子类中,并且属性的访问权限将变为protected。父类中的私有成员依然被继承下去,但是还是不能被子类访问到,会被编译器隐藏
私有继承
父类中的属性被继承到子类中,并且属性的访问权限将变为private。父类中的私有成员依然被继承下去,但是还是不能被子类访问到,会被编译器隐藏
继承中的对象模型
如若存在继承关系,并且如果我们只创建子类对象,但是这时同时也会有父类对象的创建。并且创建的顺序是:先父类,再子类。(即先走父类的构造函数,再走子类的构造函数),(析构函数是先走子类的,再走父类的)
继承中同名成员的处理
同名属性
假如子类继承了父类中的public 属性m_A,并且子类自身也有一个属性m_A,这是就会子类的m_A会隐藏从父类中继承的那份m_A,继承的那份数据不能通过子类对象直接 . 来访问,而还要加上父类作用域才可以。如:要访问子类的m_A, son.m_A即可;若要访问父类的m_A,son.Base::m_A才行
同名函数
假如子类从父类继承了一个void func(),并且自身有一个void func();
这时我们可以这样来访问子类的那份func()-- son(对象).func()或者 Son(类名)::func()
多继承
假如子类A继承了多个类,如B,C...... 并且B类和C类中均有属性m_A,除此之外,子类A自身也有一个m_A,这是也会有隐藏的效果存在;这时我们创建一个子类对象Son son;
可以这样来访问子类中的m_A属性:son.m_A
可以这样来访问B类中的m_A属性:son.B::m_A
可以这样来访问C类中的m_A属性:son.B::m_A
菱形继承
概念:Base为父类,并且有一个m_Age属性;Son_1继承Base,Son_2继承Base;
Grand_Son继承Son_1,也继承Son_2;
这时,我们Grand_Son类中会有两份m_Age属性,这是不合理的,因为一个生物时不能有两个年龄值的,这是毫无意义的。这是我们,要在Son_1和Son_2继承Base时在继承方式前加上virtual关键字,如 class Son_1 : virtual public Base......
这样做会使Base类成为虚基类。这样子类中的那两份年龄数据其实就是一份数据,两份数据的内存地址一致。他是通过虚基类指针加上偏移量来完成的。