多继承
一个派生类继承了两个或多个基类,这样的继承关系叫做多继承。
#include<iostream>
using namespace std;
class B
{
public:
B()
{
cout<<"B构造"<<endl;
}
~B()
{
cout<<"B析构"<<endl;
}
int _b;
};
class B1
{
public:
B1()
{
cout<<"B1构造"<<endl;
}
~B1()
{
cout<<"B1析构"<<endl;
}
int _b1;
};
class D:public B,public B1
{
public:
D()
{
cout<<"D构造"<<endl;
}
~D()
{
cout<<"D析构"<<endl;
}
int _d;
};
int main()
{
D d;
d._b = 1;
d._b1 = 2;
d._d = 3;
return 0;
}
如上代码,派生类D以public权限继承了基类B和基类B1。
构造函数析构函数调用顺序
构造函数调用:首先调用派生类D的构造函数,执行顺序是按照类派生列表的顺序执行的。也就是说首先会执行基类B的构造函数,之后是B1的构造函数,最后时派生类D的构造函数。
析构函数的调用:与构造函数的执行顺序相反,先析构D,之后是B1,最后是B。
派生类对象空间模型
我们去内存里面看看数据是怎么存放的。
同样是按照类派生列表的顺序从上到下存放。
菱形继承
菱形继承,就是一个派生类D多继承了两个基类C1,C2。C1,C2又同时继承了同一个基类B。这样的继承关系就叫做菱形继承,也叫钻石继承。
class B
class C1:public B
class C2:public B
class D:public C1,public C2
#include<iostream>
using namespace std;
class B
{
public:
int _b;
};
class C1:public B
{
public:
int _c1;
};
class C2:public B
{
public:
int _c2;
};
class D:public C1,public C2
{
public:
int _d;
};
int main()
{
D d;
d.C1::_b = 5;
d.C2::_b = 4;
d._c1 = 1;
d._c2 = 2;
d._d = 3;
return 0;
}
赋值结束后我们去看看内存中数据是怎么存放的
根据存放顺序我们就可以得出菱形继承的空间模型,由上到下分别是C1,C2,D。
由于C1,C2都继承了基类B,当我们直接由派生类对象d对基类B中的_b赋值时会出现下面的情况
这就是菱形继承存在的二义性问题。我们引入虚拟继承来解决这个问题。虚拟继承在下篇博客中详解。