声明一个车(vehicle)基类,具有 MaxSpeed、Weight 等保护成员变量,由此派生出自行车(bicycle)类、汽车(motorcar)类。自行车(bicycle)类有高度(Height)等保护成员变量,汽车(motorcar)类有座位数(SeatNum)等保护成员变量。从 bicycle 和 motorcar 派生出摩托车(motocycle)类,在motocycle中有成员函数Display,输出所有成员数据信息(MaxSpeed、Weight、Height、SeatNum)。 每个类型都有自己的构造函数,输出构造信息,析构函数输出析构信息。观察构造顺序和析构顺序并在程序中用注释说明。 如果不把 vehicle 设置为虚基类,会有什么问题?如何解决这个问题?编程试试看并在程序中用注释说明。 如果把vehcile设置为虚基类,请在程序中用注释说明构造函数和析构函数调用顺序。 (提示:使用new motocyle和delete操作进行测试;或者使用块语句测试)
时间: 2024-02-05 13:12:26 浏览: 76
车(Vehicle)基类,具有MaxSpeed、Weight等成员变量
5星 · 资源好评率100%
以下是代码实现,注释中有对应的说明:
```c++
#include <iostream>
using namespace std;
// 声明车(vehicle)基类
class vehicle {
protected:
int MaxSpeed;
int Weight;
public:
// 构造函数,输出构造信息
vehicle(int ms, int w): MaxSpeed(ms), Weight(w) {
cout << "构造了一个vehicle,MaxSpeed=" << MaxSpeed << ", Weight=" << Weight << endl;
}
// 析构函数,输出析构信息
~vehicle() {
cout << "销毁了一个vehicle,MaxSpeed=" << MaxSpeed << ", Weight=" << Weight << endl;
}
};
// 自行车(bicycle)类
class bicycle: virtual public vehicle { // 继承自vehicle类,并将vehicle设置为虚基类
protected:
int Height;
public:
// 构造函数,输出构造信息
bicycle(int ms, int w, int h): vehicle(ms, w), Height(h) {
cout << "构造了一个bicycle,MaxSpeed=" << MaxSpeed << ", Weight=" << Weight << ", Height=" << Height << endl;
}
// 析构函数,输出析构信息
~bicycle() {
cout << "销毁了一个bicycle,MaxSpeed=" << MaxSpeed << ", Weight=" << Weight << ", Height=" << Height << endl;
}
};
// 汽车(motorcar)类
class motorcar: virtual public vehicle { // 继承自vehicle类,并将vehicle设置为虚基类
protected:
int SeatNum;
public:
// 构造函数,输出构造信息
motorcar(int ms, int w, int sn): vehicle(ms, w), SeatNum(sn) {
cout << "构造了一个motorcar,MaxSpeed=" << MaxSpeed << ", Weight=" << Weight << ", SeatNum=" << SeatNum << endl;
}
// 析构函数,输出析构信息
~motorcar() {
cout << "销毁了一个motorcar,MaxSpeed=" << MaxSpeed << ", Weight=" << Weight << ", SeatNum=" << SeatNum << endl;
}
};
// 摩托车(motocycle)类,从bicycle和motorcar派生而来
class motocycle: public bicycle, public motorcar {
public:
// 构造函数,输出构造信息
motocycle(int ms, int w, int h, int sn): vehicle(ms, w), bicycle(ms, w, h), motorcar(ms, w, sn) {
cout << "构造了一个motocycle,MaxSpeed=" << MaxSpeed << ", Weight=" << Weight << ", Height=" << Height << ", SeatNum=" << SeatNum << endl;
}
// 析构函数,输出析构信息
~motocycle() {
cout << "销毁了一个motocycle,MaxSpeed=" << MaxSpeed << ", Weight=" << Weight << ", Height=" << Height << ", SeatNum=" << SeatNum << endl;
}
// 成员函数,输出所有成员数据信息
void Display() {
cout << "MaxSpeed=" << MaxSpeed << ", Weight=" << Weight << ", Height=" << Height << ", SeatNum=" << SeatNum << endl;
}
};
int main() {
// 测试new和delete操作
motocycle* m = new motocycle(100, 200, 50, 2);
m->Display();
delete m;
cout << endl;
// 测试块语句
{
motocycle m2(90, 180, 40, 1);
m2.Display();
}
return 0;
}
```
如果不把 vehicle 设置为虚基类,会出现如下问题:
```c++
构造了一个vehicle,MaxSpeed=100, Weight=200
构造了一个vehicle,MaxSpeed=100, Weight=200
构造了一个bicycle,MaxSpeed=100, Weight=200, Height=50
构造了一个motorcar,MaxSpeed=100, Weight=200, SeatNum=2
构造了一个motocycle,MaxSpeed=100, Weight=200, Height=50, SeatNum=2
MaxSpeed=100, Weight=200, Height=50, SeatNum=2
销毁了一个motocycle,MaxSpeed=100, Weight=200, Height=50, SeatNum=2
销毁了一个motorcar,MaxSpeed=100, Weight=200, SeatNum=2
销毁了一个bicycle,MaxSpeed=100, Weight=200, Height=50
销毁了一个vehicle,MaxSpeed=100, Weight=200
```
可以看到,vehicle类被重复构造了两次,而且析构顺序也是相反的,可能会导致程序出现未知的问题。为了解决这个问题,我们将vehicle类设置为虚基类,这样就可以共享vehicle类的成员变量,避免重复构造。修改方式如下:
```c++
// 自行车(bicycle)类
class bicycle: virtual public vehicle {
// ...
};
// 汽车(motorcar)类
class motorcar: virtual public vehicle {
// ...
};
// 摩托车(motocycle)类,从bicycle和motorcar派生而来
class motocycle: public bicycle, public motorcar {
// ...
};
```
这样,就可以避免重复构造了。同时,需要注意的是,由于vehicle类成为了虚基类,所以其构造函数和析构函数的调用顺序需要特别注意:
```c++
构造了一个vehicle,MaxSpeed=100, Weight=200
构造了一个bicycle,MaxSpeed=100, Weight=200, Height=50
构造了一个motorcar,MaxSpeed=100, Weight=200, SeatNum=2
构造了一个motocycle,MaxSpeed=100, Weight=200, Height=50, SeatNum=2
MaxSpeed=100, Weight=200, Height=50, SeatNum=2
销毁了一个motocycle,MaxSpeed=100, Weight=200, Height=50, SeatNum=2
销毁了一个motorcar,MaxSpeed=100, Weight=200, SeatNum=2
销毁了一个bicycle,MaxSpeed=100, Weight=200, Height=50
销毁了一个vehicle,MaxSpeed=100, Weight=200
```
可以看到,vehicle类的构造函数和析构函数只被调用了一次,满足了我们的需求。
阅读全文