C++继承,多重继承,虚继承的构造函数以及析构函数的调用顺序问题

时间:2023-10-15 20:56:19
#include <iostream>
using namespace std;
class A{
int data_a;
public:
A(){
data_a = ;
cout << "A" << endl;
}
A(int a){
data_a = a;
cout << "A(a)" << endl;
}
void show(){
cout << data_a << endl;
}
~A(){
cout << "~A" << endl;
}
};
class B :public A{
int data_b;
public:
B(){
data_b = ;
cout << "B" << endl;
}
B(int a, int b) :A(a){
data_b = b;
cout << "B(a)" << endl;
}
void show(){
A::show();
cout << data_b << endl;
}
~B(){
cout << "~B" << endl;
}
};
class C :public A{
int data_c;
public:
C(){ data_c = ; cout << "C" << endl; }
C(int a, int b) :A(a){
data_c = b;
cout << "C(a)" << endl;
}
void show(){
A::show();
cout << data_c << endl;
}
~C(){
cout << "~C" << endl;
}
};
class D :public B, public C{
int data_d;
public:
D(){ data_d = ; cout << "D" << endl; }
D(int a, int b, int c, int d) :B(a, b), C(a, c){
data_d = d;
cout << "D(a)" << endl;
}
void show(){
B::show();
C::show();
cout << data_d << endl;
}
~D(){
cout << "~D" << endl;
}
};
int main()
{
A a(1) ;
B b(1,2);
C c(1,3);
D d(,,,);
a.show();
b.show();
c.show();
d.show();
a.~A();
b.~B();
c.~C();
d.~D();
system("pause");
return ;
}

程序运行结果没什么好说的。

C++继承,多重继承,虚继承的构造函数以及析构函数的调用顺序问题

下面开始变了:首先

class B :virtual public A{}
class C :virtual public A{}

将B C都是虚继承A,程序输出如下:

C++继承,多重继承,虚继承的构造函数以及析构函数的调用顺序问题

这里可以看到当B和C都是虚继承A的时候,在BC初始化的时候调用了A(a),在定义并初始化D的时候,只调用了一次A()(注意这里是A(),而不是A(a),因为子类中并没有显示的调用A的构造函数,所以默认调用A的无参构造函数),所以最终D输出的值是1 2 1 3 4.同时在释放的时候也只在最后调用一次A的析构函数。

现在将B和C依次变成虚继承

1、B虚继承A,C正常继承。输出如下:

C++继承,多重继承,虚继承的构造函数以及析构函数的调用顺序问题

2、C虚继承A,B正常继承。输出如下:

C++继承,多重继承,虚继承的构造函数以及析构函数的调用顺序问题

这里可以看到总是先调用了A(),然后才依次调用带参数的构造函数。所以这里可以看到show的值有不一样的,因为虚继承调用的是不带参数的构造函数。另外调用了两次A的构造函数因此也要调用两次析构函数。注意析构函数的调用顺序。

最后我们在D的构造函数中显示的调用A的构造函数 同样四种情况

D(int a, int b, int c, int d) :B(a, b), C(a, c),B::A(a){

这里A的构造函数分别限定使用B和C。以及B和C依次虚继承。输出如下:

C++继承,多重继承,虚继承的构造函数以及析构函数的调用顺序问题

可以看出,除了构造函数的调用遵循 先虚继承后非虚继承。但是都是调用了A的带参数的构造函数。