前面介绍了单继承中派生类派生类和基类之间的关系,这一节讨论多继承问题。多继承可以看做是单继承的扩展。多继承是指一个派生类具有多个基类。派生类与每个基类之间的关系仍可看做是一个单继承,而多继承本质是实现了多个单继承的合并。
多重继承的构造函数与析构函数
派生类构造函数执行顺序是先执行所有基类的构造函数,再执行派生类本身的构造函数。处于同一层次的各基类构造函数的执行顺序取决于声明派生类时所指定的各基类的继承顺序,与派生类构造函数中所定义的成员初始化列表有关。相对应地,析构函数的调用顺序与构造函数完全相反。
说明:
如果派生类既有多个基类,又有子对象,那么派生类构造函数的调用顺序如下:
在定义派生类对象时,通过调用派生类的构造函数,首先一次调用各基类的构造函数(哪个基类先被继承,哪个基类的构造函数先被调用),然后再通过子对象名调用子对象所属类的构造函数,最后才去执行派生类构造函数自己的构造函数。
而析构函数与构造函数的执行顺序相反,首先执行派生类的析构函数,然后是子对象的析构函数,最后是各个基类的析构函数。
和单继承一样,如果在某一个基类中定义了不带参数的默认构造函数,则在派生类的构造函数的成员初始化表中可以省略对该基类构造函数的显示调用,这时候,会由系统自动隐式调用该基类的默认构造函数。
基类成员名的限定访问与同名覆盖
1.基类成员名的限定访问
在多重继承情况下,若多个基类的定义中有同名成员,则派生类对这些同名成员的访问就可能存在冲突。为避免可能出现的成员访问冲突,需要用成员名限定的方法显示地指定要访问的成员。
例:若基类A和基类B中都有同名成员x和show(),派生类C同时继承类A和类B,派生类C的对象访问这些同名成员时,将产生访问冲突。
为了解决上述成员访问冲突问题,在main()函数中,采用了成员名限定的方法对具体基类的同名成员进行访问,格式如下:
基类名::成员名
例如:c1.A::show(); c1.B::show();
即在成员名前显示指定该成员所属基类,这样就可以有效避免了对该成员访问的二义性错误(典型的菱形结构),同样对于基类的数据成员,该原则同样适用。
2.同名覆盖
前面讨论了多个基类中有同名成员的情况,可以用成员名限定法来解决这个问题。接下来再讨论当派生类中定义了与基类中同名的成员时,不加限定时是否也会出现二义性的错误呢?
答案是不会的,当派生类中定义与基类中同名的成员时,从基类中继承得到的成员被派生类的同名成员覆盖,当不加限定