分析代码示例:
#include <iostream>
using namespace std;
class X
{
public: X()
{
cout<<"X ";
}
};
class Y
{
public: Y()
{
cout<<"Y ";
}
};
class Z
{
public: Z()
{
cout<<"Z ";
}
};
class A
{
public: A()
{
cout<<"A ";
}
};
class B
{
public: B()
{
cout<<"B ";
}
};
class C : public B, virtual public A
{
public: C()
{
cout<<"C ";
}
};
class D : public B, virtual public A
{
public: D()
{
cout<<"D ";
}
};
class E : public C, virtual public D, virtual public Z
{ public:
X objX;
Y objY;
E()
{
cout<<"E ";
}
};
int main()
{
E obj;
}
输出结果:
A B D Z B C X Y E
按步骤debug:
多重继承的顺序分析
主要遵循以下几点:
1.先执行各基类的构造函数,再执行对象成员构造函数,后执行派生类构造函数
注:
①处于同一层次的各基类构造函数的执行顺序与声明派生类时所指定的各基类顺序一致,而与派生类的构造函数定义中初始化列表顺序无关。
②若父类构造函数带有参数,必须在最远继承子类初始化列表调用。
2.析构函数的执行顺序与构造函数相反。
3.若同一层次中同时包含虚基类和非虚基类,先调用虚基类的构造函数,再调用非虚基类的构造函数。
4.同一层次中的非虚基类只调用一次。
5.如果派生类的成员与基类的某个成员同名,则派生类将在其作用域隐藏掉该基类成员。(C++ Prime 5)
依据如上分析,则示例代码中:
由3,找到classD
由3,找到classA并执行A()
由1,找到classB并执行B()
由1,执行classD的D()
由3,找到classZ并执行Z()
由3,找到classC
由4,找到classB并执行B()
由1,找到classX并执行X()
由1,找到classY并执行Y()
由1,执行E()
得到结果A B D Z C B X Y E