派生类都只有一个基类,称为单继承。除此之外,C++也支持多继承,即一个派生类可以有两个或多个基类。
多继承的语法也很简单,将多个基类用逗号隔开。
例如已声明了类A、类B和类C,那么可以这样来声明派生类D:
class D: public A, private B, protected C
{
//类D新增加的成员
}
D 是多继承形式的派生类,它以公有的方式继承 A 类,以私有的方式继承 B 类,以保护的方式继承 C 类。D 根据不同的继承方式获取 A、B、C 中的成员,确定它们在派生类中的访问权限。
与单继承形式基本相同,只是在派生类的构造函数中调用多个基类的构造函数。
以上面的 A、B、C、D 类为例,D 类构造函数的写法为:
D(形参列表): A(实参列表), B(实参列表), C(实参列表)
{
//其他操作
}
多继承的实例
#include
using namespace std;
//基类
class BaseA{
public:
BaseA(int a, int b);
~BaseA();
protected:
int m_a;
int m_b;
};
BaseA::BaseA(int a, int b): m_a(a), m_b(b){
cout<<"BaseA constructor"<<endl;
}
BaseA::~BaseA(){
cout<<"BaseA destructor"<<endl;
}
//基类
class BaseB{
public:
BaseB(int c, int d);
~BaseB();
protected:
int m_c;
int m_d;
};
BaseB::BaseB(int c, int d): m_c(c), m_d(d){
cout<<"BaseB constructor"<<endl;
}
BaseB::~BaseB(){
cout<<"BaseB destructor"<<endl;
}
//派生类
class Derived: public BaseA, public BaseB{
public:
Derived(int a, int b, int c, int d, int e);
~Derived();
public:
void show();
private:
int m_e;
};
Derived::Derived(int a, int b, int c, int d, int e): BaseA(a, b), BaseB(c, d), m_e(e){
cout<<"Derived constructor"<<endl;
}
Derived::~Derived(){
cout<<"Derived destructor"<<endl;
}
void Derived::show(){
cout<<m_a<<", "<<m_b<<", "<<m_c<<", "<<m_d<<", "<<m_e<<endl;
}
int main(){
Derived obj(1, 2, 3, 4, 5);
obj.show();
return 0;
}
运行结果
BaseA constructor
.BaseB constructor
Derived constructor
1,2,3,4,5
Derived destructor
BaseB destructor
BaseA destructor
从运行结果来看,多继承形式下析构函数的执行顺序和构造函数的执行顺序相反。
当两个或多个基类有同名成员时,如果直接访问该成员,就会产生命名冲突,编译器不知道使用哪个基类的成员。这个时候需要在名字前面加上类名和域解析符::,以显示地指明到底使用哪个类的成员,消除二义性。
#include
using namespace std;
//基类
class BaseA{
public:
BaseA(int a, int b);
~BaseA();
public:
void show();
protected:
int m_a;
int m_b;
};
BaseA::BaseA(int a, int b): m_a(a), m_b(b){
cout<<"BaseA constructor"<<endl;
}
BaseA::~BaseA(){
cout<<"BaseA destructor"<<endl;
}
void BaseA::show(){
cout<<"m_a = "<<m_a<<endl;
cout<<"m_b = "<<m_b<<endl;
}
//基类
class BaseB{
public:
BaseB(int c, int d);
~BaseB();
void show();
protected:
int m_c;
int m_d;
};
BaseB::BaseB(int c, int d): m_c(c), m_d(d){
cout<<"BaseB constructor"<<endl;
}
BaseB::~BaseB(){
cout<<"BaseB destructor"<<endl;
}
void BaseB::show(){
cout<<"m_c = "<<m_c<<endl;
cout<<"m_d = "<<m_d<<endl;
}
//派生类
class Derived: public BaseA, public BaseB{
public:
Derived(int a, int b, int c, int d, int e);
~Derived();
public:
void display();
private:
int m_e;
};
Derived::Derived(int a, int b, int c, int d, int e): BaseA(a, b), BaseB(c, d), m_e(e){
cout<<"Derived constructor"<<endl;
}
Derived::~Derived(){
cout<<"Derived destructor"<<endl;
}
void Derived::display(){
BaseA::show(); //调用BaseA类的show()函数
BaseB::show(); //调用BaseB类的show()函数
cout<<"m_e = "<<m_e<<endl;
}
int main(){
Derived obj(1, 2, 3, 4, 5);
obj.display();
return 0;
}
运行结果
BaseA constructor
BaseB constructor
Derived constructor
m_a = 1
m_b = 2
m_c = 3
m_d = 4
m _e = 5
Derived destructor
BaseB destructor
BaseA destructor
#include
using namespace std;
//基类A
class A{
public:
A(int a, int b);
protected:
int m_a;
int m_b;
};
A::A(int a, int b): m_a(a), m_b(b){ }
//基类B
class B{
public:
B(int b, int c);
protected:
int m_b;
int m_c;
};
B::B(int b, int c): m_b(b), m_c(c){ }
//派生类C
class C: public A, public B{
public:
C(int a, int b, int c, int d);
public:
void display();
private:
int m_a;
int m_c;
int m_d;
};
C::C(int a, int b, int c, int d): A(a, b), B(b, c), m_a(a), m_c(c), m_d(d){ }
void C::display(){
printf("A::m_a=%d, A::m_b=%d\n", A::m_a, A::m_b);
printf("B::m_b=%d, B::m_c=%d\n", B::m_b, B::m_c);
printf("C::m_a=%d, C::m_c=%d, C::m_d=%d\n", C::m_a, C::m_c, m_d);
}
int main(){
C obj_c(10, 20, 30, 40);
obj_c.display();
return 0;
}
运行结果
A: :m_a=10,A: :m_b=20
B: :m_b=20,B::m_c=30
c: :m_a=10,C::m_c=30,C::m_d=40
A、B 是基类,C 是派生类,假设 obj_c 的起始地址是 0X1000,那么 obj_c 的内存分布如下图所示:
基类对象的排列顺序和继承时声明的顺序相同。