虚基类
解决多重继承中,一个公共基类可能在派生类中产生多个拷贝的现象。
如:有一个公共基类A,类B和类C都有类A派生,类D由类B和类C派生,则类D含有类A的两个拷贝,这不仅多占内存,还可能造成多个拷贝中的数据不一致。
#include <iostream>
using namespace std;
class A {
public:
int x;
A(int a = 0) { x = a; }
};
class B:public A {
public:
int y;
B(int a = 0, int b = 0):A(b) { y = a; }
void PB() { cout << "x=" << x << "y=" << y << '\n'; }
};
class C:public A {
public:
int z;
C(int a = 0, int b = 0):A(b) { z = a; }
void PC() { cout << "x=" << x << "z=" << z << '\n'; }
};
class D:public B, public C {
public:
int m;
D(int a, int b, int d, int e, int f):B(a, b), C(d, e) { m = f; }
void Print() {
PB();
PC();
cout << "m=" << m << '\n';
}
};
int main(void)
{
D d(100, 200, 300, 400, 500);
d.Print();
return 0;
}
x=200y=100
x=400z=300
m=500
D中包含类A的两个拷贝,从两个不同的x可以看出来。
在多重接继承中,如果希望公共基类在派生类中只有一个拷贝,可在定义派生类时将公共基类的类名前加上virtual即可。
#include <iostream>
using namespace std;
class A {
public:
int x;
A(int a = 0) { x = a; }
};
class B:virtual public A { //加virtual
public:
int y;
B(int a = 0, int b = 0):A(b) { y = a; }
void PB() { cout << "x=" << x << "y=" << y << '\n'; }
};
class C:virtual public A { //加virtual
public:
int z;
C(int a = 0, int b = 0):A(b) { z = a; }
void PC() { cout << "x=" << x << "z=" << z << '\n'; }
};
class D:public B, public C {
public:
int m;
D(int a, int b, int d, int e, int f):B(a, b), C(d, e) { m = f; }
void Print() {
PB();
PC();
cout << "m=" << m << '\n';
}
};
int main(void)
{
D d(100, 200, 300, 400, 500);
d.Print();
return 0;
}
x=0y=100
x=0z=300
m=500
解释:先调用虚基类的构造函数,然后调用非虚基类的构造函数。
类D的构造函数分别调用类B和类C的构造函数,由于类A在类D中只有一个拷贝,编译器无法确定是由类B还是类C的构造函数来调用类A的构造函数,这种情况下,编译器约定执行类B和类C的构造函数时都不调用虚基类A的构造函数,二是子类D的构造函数中直接调用虚基类A的默认构造函数,因此x为0.

浙公网安备 33010602011771号