在前面的示例中,派生类只有一个基类,称为单继承 ( )。 另外,C++还支持多重继承(),即一个派生类可以有两个或多个基类。
多重继承往往会使代码逻辑变得复杂和混乱。 它一直存在争议,并且很少在中小型项目中使用。 后来Java、C#、PHP等干脆取消了多重继承。
多重继承的语法也很简单,多个基类用逗号分隔即可。 例如,如果已经声明了类A、类B和类C,则派生类D可以这样声明:
D 类:A、B、C{
//新添加的D类成员
D是多重继承形式的派生类,它以公有方式继承类A,以私有方式继承类B,以受保护方式继承类C。 D根据不同的继承方式获取A、B、C的成员,并确定其在派生类中的访问权限。
多重继承形式下的构造函数与单继承形式基本相同,只不过需要在派生类的构造函数中调用多个基类的构造函数。 以上面的A、B、C、D类为例,D类的构造函数写如下:
D(形参列表): A(实参列表), B(实参列表), C(实参列表){
// 其他操作
基类构造函数的调用顺序与它们在派生类构造函数中出现的顺序无关,但与声明派生类时基类出现的顺序相同。 仍然以上面的类A、B、C、D为例,即使类D的构造函数写成下面的形式:
D(形参列表): B(实参列表), C(实参列表), A(实参列表){
// 其他操作
然后先调用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"<seA::~baseA(){
cout<<"baseA destructor"<seB{
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"<seB::~baseB(){
cout<<"baseB destructor"<seA, 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"<
运行结果:
碱基A
基地B
1, 2, 3, 4, 5
基地B
碱基A
从运行结果还可以发现,多重继承形式的析构函数的执行顺序与构造函数相反。
命名冲突
当两个或多个基类中存在同名成员时,如果直接访问该成员,就会发生命名冲突,编译器不知道该使用基类的哪个成员。 这时候就需要在成员名前面加上类名和域解析器::,以明确表明使用的是哪个类成员,消除歧义。
修改上面的代码,在baseA和baseB类中添加show()函数,并将该类的show()函数重命名为():
#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"<seA::~baseA(){
cout<<"baseA destructor"<seA::show(){
cout<<"m_a = "<seB{
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"<seB::~baseB(){
cout<<"baseB destructor"<seB::show(){
cout<<"m_c = "<seA, 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"<seA::show(); //调用baseA类的show()函数
baseB::show(); //调用baseB类的show()函数
cout<<"m_e = "<
读者应该注意第64行和第65行,我们明确指出要调用哪个基类的show()函数。