虚继承:主要解决棱形继承时,出现的内存访问冲突问题。
声明格式:class 类名 :virtual 继承方式 类名
继承方式可以缺省,缺省之后默认继承方式为 private 私有继承。
注意,代码中class D的初始化列表顺序需要为A ->B -> C,也就是实际执行时,构造函数的调用顺序。
#include <iostream>
#include <string>
using namespace std;
class A {
public:
A(int a) : ma(a) { cout << " A constructor. ma = " << ma << endl; }
~A() { cout << " A destructor. " << endl; }
public:
int ma;
};
class B : virtual public A {
public:
B(int b) : A(b), mb(b) {
cout << " B constructor. mb = " << mb << " ma =" << ma << endl;
}
~B() { cout << " B destructor. " << endl; }
public:
int mb;
};
class C : virtual public A {
public:
C(int c) : A(c), mc(c) {
cout << " C constructor. mc = " << mc << " ma =" << ma << endl;
}
~C() { cout << " C destructor. " << endl; }
public:
int mc;
};
class D : public B, public C {
public:
D(int d) : A(d + 3), B(d + 1), C(d + 2), md(d) {
cout << " D constructor. " << endl;
}
~D() { cout << " D destructor. " << endl; }
public:
int md;
};
int main() {
D d(10);
cout << " " << d.ma << " " << d.mb << " " << d.mc << " " << d.md << endl;
return 0;
}
使用虚继承时的 打印结果:
A constructor. ma = 13
B constructor. mb = 11 ma =13
C constructor. mc = 12 ma =13
D constructor.
13 11 12 10
D destructor.
C destructor.
B destructor.
A destructor.
注意,如果不使用虚继承,将virtual 去掉,编译执行也是没问题的,打印结果如下。可以看到 A 的构造函数被调用了两次,ma的值是不一样的。
A constructor. ma = 11
B constructor. mb = 11 ma =11
A constructor. ma = 12
C constructor. mc = 12 ma =12
D constructor.
11 12 10
D destructor.
C destructor.
A destructor.
B destructor.
A destructor.