我们先来看一段简单的代码:
#include <iostream>
class Vehicle
{
public:
Vehicle(double x = 0.0, double y = 0.0);
};
Vehicle::Vehicle(double x, double y)
{
cout << "Vehicle construct: x=" << x << " y=" << y << endl;
}
class Land_vehicle : public virtual Vehicle
{
public:
Land_vehicle(double x = 0.0, double y = 0.0);
};
Land_vehicle::Land_vehicle(double x, double y)
:Vehicle(x, y)
{
cout<<"Land_vehicle x="<<x<<" y="<< y << endl;
}
class Tank : public Land_vehicle
{
public:
Tank(double x = 0.0, double y = 0.0);
};
Tank::Tank (double x, double y)
:Land_vehicle(x,y){
cout << "Tand construct: x="<<x <<" y="<< y << endl;
}
int main ()
{
Tank t(1.0, 2.0);
cout<<"----------------"<<endl;
Land_vehicle lv(1.0, 2.0);
}
代码继承关系很简单:
Vehicle <--- Land_vehicle < ---- Tank;
但是我们执行结果却如下:
可以发现问题,在Tank类构造Vehicle的时候,参数x, y并没有如预期般传给构造函数。
解答过程如下:
这是因为虚基类Vehicle的初始化是在最外层的派生类(在本例中的Tank)中进行的。由于Tank的构造函数并没有明确地初始化Vehicle, 所以程序就自动调用了Vehicle的缺省构造构造函数。在Land_vehicle中对Vehiicle的初始化在本例中没有被执行--因为Land_vehicle并不是最外层的派生类。
如果要修正这个bug, 我们就必须在每个构造函数添加对虚基类的初始化
Tank::Tank (double x, double y)
:Land_vehicle(x,y), Vehicle(x, y){
cout << "Tand construct: x="<<x <<" y="<< y << endl;
}