虚基类

解决多重继承中,一个公共基类可能在派生类中产生多个拷贝的现象。

如:有一个公共基类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.

原文地址:https://www.cnblogs.com/helloweworld/p/2840992.html