单继承或单基派生: 派生类只有一个基类
多重继承或多基派生: 派生类具有两个或多个基类时
一、多重继承派生类的声明
声明时只需将要继承的多个基类用逗号分隔,声明的一般形式为:
class 派生类名:继承方式1 基类名1,··· ···,继承方式n 基类名n{
派生类新增的数据成员和成员函数
}
冒号后面的部分称为基类表,各基类之间用逗号分隔,其中“继承方式 i ”(i=1,2,··· ,n),规定了派生类从基类中按什么方式继承:private,protected或 public。默认的继承方式是 private。
例 1:继承方式举例
class z:public x,y{
//类 z 公有继承了类 x,私有继承了类 y
···
};
class z:x,public y{
//类 z 私有继承了类 x,公有继承了类 y
···
};
class z:public x,public y{
//类 z 公有继承了类 x,公有继承了类 y
···
};
例 2:多重继承情况下派生类的访问特性
#include<iostream>
using namespace std;
class X{
private:
int a;
public:
void setx(int x){
a=x;
}
void showx(){
cout<<"a="<<a<<endl;
}
};
class Y{
private:
int b;
public:
void sety(int x){
b=x;
}
void showy(){
cout<<"b="<<b<<endl;
}
};
class Z:public X,private Y{
//声明派生类 Z,公有继承类 X,私有继承类 Y
private:
int c;
public:
void setz(int x,int y){
c=x;
sety(y);
}
void showz(){
showy();
cout<<"c="<<c<<endl;
}
};
int main(){
Z obj;
obj.setx(3);
obj.showx();
// obj.sety(4); //错误,成员函数 sety 在 Z 中是私有成员
// obj.showy(); //错误,成员函数 showy 在 Z 中是私有成员
obj.setz(5,6);
obj.showz();
return 0;
}
例 3:对基类成员的访问必须是无二义的
class X{
public f();
};
class Y{
public:
int f();
int g();
};
class Z:public X,public Y{
public:
int g();
int h();
};
如定义类 Z 的对象 obj:
Z obj;
则以下对函数 f() 的访问是二义的:
obj.f(); //二义性错误,不知调用的是类 X 的 f(),还是类 Y 的 f()
使用成员名限定可以消除二义性:
obj.X::f(); //调用类 X 的 f()
obj.Y::f(); //调用类 Y 的 f()
二、多重继承派生类的构造函数和析构函数
多重继承下派生类构造函数定义的一般形式为:
派生类名(参数总表):基类名1(参数表1),基类名2(参数表2),···,基类名n(参数表n){
派生类新增成员的初始化语句
}
多重继承下派生类构造函数与单继承下派生类构造函数相似,它必须同时负责该派生类所有基类构造函数的调用。同时,派生类的参数个数必须包含完成所有基类初始化所需的参数个数。
多重继承的构造函数的执行顺序与单继承构造函数的执行顺序相同:先执行基类的构造函数(处于同一层次的各个基类构造函数的执行顺序,取决于声明派生类时所指定的各个基类的顺序),再执行对象成员的构造函数,最后执行派生类构造函数体的原则。
例 4:现有一个窗口类 Window 和一个滚动条类 Scrollbar,它们可以共同派生出一个带有滚动条的窗口,声明如下:
class Window{
//声明窗口类
```
public:
Window(int top,int left,int bottom,int right);
~Window(