多重继承
前面说的都是从一个父类派生出来的子类,这一节看从多个父类派生子类,叫做多重继承。举个例子,西红柿可以作为水果,也可以作为蔬菜,既能作为水果吃,也能炒菜吃。所以就可以从水果类和蔬菜类派生出西红柿类。多重继承的类的定义方式为:
class 子类名: 继承方式 父类1,继承方式 父类2...
{
新成员的定义
};
可以用不同的继承方式继承不同的父类。例如西红柿类可以Public的继承水果类,Private的继承蔬菜类,访问权限跟前面讲的一样。
多重继承的构造函数的定义方式前面有,注意调用顺序为先调用父类1的构造函数,再调用父类2的构造函数,最后调用子类的构造函数。析构函数的顺序正好相反。
二义性问题1
父类A中有函数名为func,没有参数,父类B中也有函数名为func,没有参数,一个子类Public的继承父类A和父类B。那么通过子类的对象访问func函数时,到达是调用父类A的func呢?还是父类B的func呢?这就是二义性问题,解决方法有两种
1.调用时明确写出。例如子类对象名为obj,调用时写obj.A::func();
2.在子类中重新定义func函数。重新定义并不是重载,重载需要参数不同的,而子类中重新定义是参数、返回值、函数名统统一样。
从方法2,可以看出调用顺序,程序会先去找子类中有没有func的定义,如果有,就直接执行子类中的func函数,如果没有再去父类中找,没找到就报错。
二义性问题1
还有一种二义性问题,如下:
class Base
{
public:
int b;
};
class Base1:public Base
{
public:
int b1;
};
class Base2:public Base
{
public:
int b2;
};
class Child:public Base1,public Base2
{
public:
int func(){return Base1::b+Base2::b};
};
Child类有两个父类:Base1和Base2,这两个父类继承自同一个爷爷类,Base。
声明Child类的对象c,通过c访问父类的公有成员b,会报错的,因为不知道是父类Base1的,还是Base2的。可以这样写c.Base1::b;或者c.Base2::b;来访问避免二义性