1.训练要点:
- 掌握继承和多态知识点;
- 掌握抽象类的概念;
- 掌握纯虚函数的使用。
2.需求说明
利用继承和多态知识点为汽车租赁中心开发一个汽车租赁系统,对租赁中心的汽车进行管理,主要如下:
(1)基本功能:首先,输入租赁的天数,用于最后计算租赁的费用;其次,选择租赁的汽车类型、其次品牌、汽车型号和客车座位数;最后,系统给出分配的车辆信息和需要支付的租赁费用,以及计算出汽车租赁的总租金;
(2)汽车租赁公司出租多种车辆,车型及租金情况可以参考下图左:
(3)类的设计可以参考下可以参考下图右:
一、代码核心功能与架构
此 C++ 代码构建汽车租赁系统,以基类 MotoVehicle
及派生类 Car
、Bus
为核心,借助继承和多态处理租赁业务,用指针数组管理租赁车辆对象。
二、类的设计精要
(一)基类 MotoVehicle
- 成员变量:
vId
标识车辆,brand
记录品牌,perRent
定日租金,day
存租赁天数,这些变量在租赁各环节都至关重要。 - 构造函数:初始化成员变量,为对象创建赋初值。
- 纯虚函数
calRent
:强制派生类实现各自租金计算逻辑,实现多态,使系统能统一处理不同车辆租金计算。 - 获取函数:方便外部获取对象内部信息,遵循封装原则,促进代码模块交互。
(二)派生类 Car
type
变量:明确轿车具体类型,利于精准业务管理与运营,如优惠策略制定与车辆推荐。- 构造函数:先调用基类构造初始化继承属性,再初始化自身
type
属性,确保对象完整准确。 - 重写
calRent
函数:按日租金乘租赁天数计算,契合轿车租赁常见模式,融入多态框架。
(三)派生类 Bus
seatCount
变量:记录客车座位数,是客车租赁业务关键,影响用途、定价与业务流程多方面。- 构造函数:类似
Car
类构造,初始化基类与自身属性。 - 重写
calRent
函数与预留函数:当前租金计算简单,预留leaseOutFlow
函数为复杂业务流程扩展留空间。
三、主函数业务逻辑解读
(一)变量初始化与数据准备
rentV
指针数组:存储租赁车辆对象指针,管理不同类型车辆,是系统数据核心。Count
与totalRent
变量:Count
计租赁车辆数,totalRent
累总租金,分别反映业务规模与成本。
(二)租赁选择循环
- 信息获取:先获租赁天数存
dayss
,再让用户选车辆类型存vehicleType
。 - 轿车租赁分支:若选轿车,进一步获品牌与型号信息,依此创建
Car
对象存rentV
数组并更新Count
。 - 客车租赁分支:选客车时,获取品牌与座位数信息,创建
Bus
对象存入数组并更新Count
。 - 是否继续租赁判断:每辆车租赁信息输入后,询问用户是否继续,依选择决定循环走向。
(三)租赁信息展示与租金计算
- 表头输出:格式化输出租赁信息表头,使展示美观易读。
- 循环处理:遍历
rentV
数组,用多态调用calRent
计算租金,累加到totalRent
并输出每辆车信息。 - 汇总输出:展示租赁车辆总数与总费用,总结业务情况。
(四)内存释放
循环释放 rentV
数组中动态分配对象内存,防内存泄漏,保障系统资源管理良好。
#include <iostream>
#include<iomanip>
using namespace std;
// 定义基类MotoVehicle,作为车辆相关信息和行为的抽象基类
class MotoVehicle {
protected:
string vId; // 车辆的编号(车牌号等类似标识),受保护成员变量,派生类可访问
string brand; // 车辆品牌,受保护成员变量,派生类可访问
int perRent; // 车辆每日的租金,受保护成员变量,派生类可访问
int day; // 用于记录当前租赁相关操作中的租赁天数,受保护成员变量,派生类可访问
public:
// 构造函数,用于初始化车辆的编号、品牌、每日租金和租赁天数
MotoVehicle(string id, string brand, int rent, int Days) : vId(id), brand(brand), perRent(rent), day(Days) {}
// 纯虚函数,用于计算租赁指定天数的租金,具体计算逻辑由派生类实现,体现多态性
virtual float calRent(int days) = 0;
// 获取车辆编号的函数
string getVehicleId() { return vId; }
// 获取车辆品牌的函数
string getBrand() { return brand; }
// 获取车辆每日租金的函数
int getPerRent() { return perRent; }
// 获取当前记录的租赁天数的函数
int getdays() { return day; }
};
// 定义派生类Car,表示轿车,继承自sys类
class Car : public MotoVehicle {
private:
string type; // 轿车的具体类型(例如车型等更详细分类)
public:
// 构造函数,调用基类的构造函数来初始化从基类继承的属性,并初始化自身特有的轿车类型属性
Car(string id, string brand, int rent, int Days, string carType) : MotoVehicle(id, brand, rent, Days), type(carType) {}
// 重写基类的calRent函数,按照轿车的租金计算方式(简单的日租金乘以租赁天数)来计算总租金
float calRent(int days) { return perRent * days; }
};
// 定义派生类Bus,表示客车,继承自sys类
class Bus : public MotoVehicle {
private:
int seatCount; // 客车的座位数量
public:
// 构造函数,调用基类的构造函数来初始化从基类继承的属性,并初始化自身特有的座位数属性
Bus(string id, string brand, int rent, int Days, int seats) : MotoVehicle(id, brand, rent, Days), seatCount(seats) {}
// 重写基类的calRent函数,按照客车的租金计算方式(当前也是简单的日租金乘以租赁天数)来计算总租金
float calRent(int days) { return perRent * days; }
// 空函数,当前可能预留用于客车租赁相关的特定流程处理,暂时未实现具体功能
void leaseOutFlow() {}
};
int main() {
MotoVehicle* rentV[1000]; // 创建一个MotoVehicle类型的指针数组,用于存储租赁的各种车辆对象的指针,最多可存储1000辆车的信息
int Count = 0; // 用于记录已经租赁的车辆数量
int totalRent = 0; // 用于累计所有租赁车辆的总租金
int dayss; // 用于临时存储用户输入的租赁天数
while (1) {
int vehicleType;
cout << "***********欢迎光临腾飞汽车租聘公司***********" << endl;
cout << "请输入租赁天数:";
cin >> dayss; // 获取用户输入的租赁天数
cout << "请选择要租赁的汽车类型(1为轿车,2为客车):";
cin >> vehicleType; // 获取用户选择的汽车类型
if (vehicleType == 1) { // 如果用户选择租赁轿车
string brand;
int model;
cout << "请输入汽车品牌(1为别克,2为宝马):";
cin >> brand; // 获取用户输入的轿车品牌
if (brand == "1")
cout << "请选择轿车型号(1为林荫大道,2为GL8):";
else
cout << "请选择轿车型号(1为550i,2为X6):";
cin >> model; // 获取用户选择的轿车型号
if (brand == "1") {
brand = "别克";
if (model == 1) {
// 根据用户选择的品牌、型号等信息创建轿车对象,并将对象指针存入rentV数组,同时更新已租赁车辆数量Count
rentV[Count++] = new Car("京001", brand, 300, dayss, "林荫大道");
}
else if (model == 2) {
rentV[Count++] = new Car("京002", brand, 600, dayss, "GL8");
}
}
else if (brand == "2") {
brand = "宝马";
if (model == 1) {
rentV[Count++] = new Car("京003", brand, 600, dayss, "550i");
}
else if (model == 2) {
rentV[Count++] = new Car("京004", brand, 800, dayss, "X6");
}
}
}
else if (vehicleType == 2) { // 如果用户选择租赁客车
string brand;
int seats;
cout << "请输入客车品牌(1为金杯,2为金龙):";
cin >> brand; // 获取用户输入的客车品牌
cout << "请输入客车座位数:";
cin >> seats; // 获取用户输入的客车座位数
if (brand == "1") {
brand = "金杯";
if (seats <= 16)
// 根据用户选择的品牌、座位数等信息创建客车对象,并将对象指针存入rentV数组,同时更新已租赁车辆数量Count
rentV[Count++] = new Bus("浙001", brand, 800, dayss, seats);
else
rentV[Count++] = new Bus("浙002", brand, 1500, dayss, seats);
}
else if (brand == "2") {
brand = "金龙";
if (seats <= 16)
rentV[Count++] = new Bus("浙001", brand, 300, dayss, seats);
else
rentV[Count++] = new Bus("浙002", brand, 1500, dayss, seats);
}
}
char choice;
cout << "是否继续租赁?(y/n):";
cin >> choice; // 获取用户是否继续租赁的选择
if (choice == 'n') break; // 如果用户选择不继续租赁(输入'n'),则跳出循环,结束车辆租赁选择过程
}
cout << "租赁信息如下:\n";
cout << "序号" << setw(15) << "车辆信息" << setw(15) << "车牌号" << setw(15) << "租赁天数" << setw(15) << "金额 \n";
for (int i = 0; i < Count; ++i) {
MotoVehicle* vehicle = rentV[i]; // 获取当前租赁车辆的指针
int rent = vehicle->calRent(vehicle->getdays()); // 调用车辆对象的calRent函数计算该车辆的租金
totalRent += rent; // 将该车辆的租金累加到总租金中
cout << setw(1) << i + 1 << setw(16) << vehicle->getBrand() << setw(16) << vehicle->getVehicleId() << setw(13) << vehicle->getdays() << setw(15) << rent << "元\n";
}
cout << endl;
cout << "共租赁 " << Count << " 辆车,总费用为 " << totalRent << " 元\n";
// 释放之前动态分配的车辆对象所占用的内存,防止内存泄漏
for (int i = 0; i < Count; ++i) {
delete rentV[i];
}
return 0;
}