声明多重继承的方式
前面介绍的继承方式都是单继承,即派生类的基类只有一个。现实世界中,一个派生类往往会有多个基类。比如沙发床,是沙发和床的功能的组合,水鸟,既具有鸟的特点,在天空飞翔,又能够像鱼一样,在水里遨游,这些都是多重继承的体现。水鸟的多重继承结构如图1所示。
图1 水鸟的多重继承结构
多重继承可以看做是单继承的扩展,定义形式与单继承类似,其语法形式如下所示:
class 派生类名:继承方式 基类1名称,继承方式 基类2名称,…,继承方式n 基类n名称
{
public:
新增加的公有成员
protected:
新增加的保护成员
private:
新增加的私有成员
};
通过多继承,派生类会从多个基类中继承成员。在普通多继承方式下,若定义派生类对象,其中的数据成员的排列规则是:首先按照派生类定义形式中基类的排列顺序,将基类成员依次排列,接下来再存放派生类中新添加的数据,假设有如下代码:
class Base1{ //定义基类Base1
public:
void func_base1();
private:
int n_base1;
int m_base1;
};
class Base2{ //定义基类Base2
public:
void func_base2();
private:
int n_base2;
int m_base2;
};
//定义派生类Derive,继承自Base1和Base2
class Derive:public Base1, public Base2{
public:
void func_derive();
private:
int n_derive;
};
上述代码中派生类Derive继承自基类Base1和Base2,若定义派生类对象,则其中的数据成员排列形式如图2所示。
图2 多重继承中派生类成员的排列形式
由图2可以看出,对于派生类Derive的对象来说,它将基类Base1的成员排列在最前端,第二个基类Base2的数据紧随其后,派生类自身的成员在最后存放,这种排列方式,使得不同类型的指针变量访问数据时操作比较简单,只需要从起始址开始,改变固定的偏移量即可。
接下来通过一个案例来说明采用多继承方式时派生类的定义及使用,如例1所示。
例1
1 #include <iostream>
2 using namespace std;
3
4 class Bird //定义鸟类
5 {
6 public:
7 //定义鸟在天空飞的成员函数
8 void fly_in_sky() { cout << "bird fly in sky!" << endl; }
9 //定义鸟呼吸的成员函数
10 void breath() { cout << "bird breath!" << endl; }
11 };
12 class Fish //定义鱼类
1 {
2 public:
3 //定义鱼在水里游的成员函数
4 void swim_in_water() { cout << "fish swim in water!" << endl; }
5 //定义鱼呼吸的成员函数
6 void breath() { cout << "fish breath!" << endl; }
7 };
8 class WaterBird:public Bird, public Fish //定义水鸟类
9 {
10 public:
11 //定义水鸟行为的成员函数
12 void fly_swim() { cout << "waterbird cant fly and swim!" << endl; }
13 };
14 int main()
15 {
16 WaterBird waterbird; //定义水鸟对象
17 waterbird.fly_in_sky(); //调用从鸟类继承来的flyinsky()函数
18 waterbird.swim_in_water(); //调用从鱼类继承来的swiminwater()函数
19 system("pause");
20 return 0;
21 }
程序运行结果如图3所示。
图3 通过多重继承定义派生类
例1中定义了三个类Bird、Fish、WaterBird。WaterBird多重继承自Bird和Fish,因此WaterBird自然继承了鸟类和鱼类的所有成员,并能够访问其中的公有和受保护成员,在主函数中定义派生类对象并调用基类成员函数fly_in_sky()和swim_in_water(),程序运行正确。