Project 3
Build an object-oriented library which can be used to track automobile maintenance. There can be different car types such as petrol, diesel, gas, electric etc., This library should be able to support at least three of the car types.
Maintenance tasks include activities like oil change or replace oil filter, replace air filter, replace fuel filter, tire rotations, infotainment system debug, replace spark plugs, replace the cabin or a/c filter, check the level and refill clutch fluid or brake fluid, examine belts, wipers, hoses, check the tire conditions, check the charging systems and battery.
Every vehicle should have the following details:
-
Make
-
Model
-
Year
-
Odometer reading
The library interfaces or the API’s (Application Program Interface) should be capable of adding, updating, listing and removing the entries at runtime.
Consider there are three classes such as
-
Vehicle
-
This class includes protected members such as Make, Model, Year and Odometer. These members are initialized using the class constructor.
-
The functions include getter and setter functions of Make(), Model(), Year() and Odometer().
-
Maintenance activities that should be done are checkTireRotation(), getCarInformation()
-
Let the three fuel types be
enum Type{
GAS,
DIESEL,
ELECTRIC
};
-
Let there be a pure virtual method to get the fuel type i.e.,
-
virtual Type getType() = 0;
-
GasCar
-
This is inherited from the vehicle class and has functions getType() and getFuelType()
-
DieselCar
-
This class is also a subclass of vehicle and the functions include getFuelType() and getType()
-
ElectricCar
-
checkTireRotation()- based on odometer reading, we decide whether the car needs to rotate tires or not.
-
checkChargerPower- based on odometer reading this advices to recharge power
-
getType() – to get the fuel type
-
-
This is a subclass of Vehicle class and methods include
-
FuelVehicle
-
This is an abstract class that inherits vehicle class. The methods in this class include checkOil() and pure virtual function getFuelType()
Maintenance activities that has to be done are as follows,
-
Check tire rotation: Let the tire cycle be 50,000 km. Calculate the distance the car has run and if this distance run is at 50k km, then advise rotation, else tires are good to go. Also, calculate the remainder of each 50k km, If remainder >=0 then advice to rotate tires.
-
Check Power: Let the distance be 400km, If the distance the car has run is at 400km, then advise battery to be recharged else your vehicle is good to go.
Now that we have learnt about the classes to be created, we need to write our driver code i.e., main.cpp
-
In the main class, initialize the inventory and ask the user to select whether to add, update, list or delete the Vehicle list.
-
addVehicle() – to add new vehicle to inventory
-
ListVehicle()- to list the vehicles in the inventory
-
UpdateVehicle()- to update the vehicle in the inventory list
-
RemoveVehicle()- to remove the vehicle from the inventory list
-
Tire Rotation() – Check if tires need rotation
-
OilChange()- check if car requires oil change
-
Recharge() – check if vehicle needs recharge
-
Check for the user input, 0-1-2-3-4-5-6-7, Functions will be called based on the input provided by the user. If the input is wrong, ask again.
-
Menu should be as below,
|
<< " 0. Quit.\n" |
|
|
<< " 1. List inventory.\n" |
|
|
<< " 2. Add vehicle.\n" |
|
|
<< " 3. Update vehicle\n" |
|
|
<< " 4. Remove vehicle\n" |
|
|
<< " 5. Tire Rotation\n" |
|
|
<< " 6. Oil Change\n" |
|
|
<< " 7. Recharge\n" |
|
-
Retrieve the user input on the vehicle’s make, model, year, type and odometer.
-
getNewMake() – If input is blank, request again
-
getNewModel() – If input is blank, request again
-
getYear() – If input doesn’t have 4 digits, request again
-
getNewOdometer()- Input should be only numericals
-
getNewType() – Input should be within 0-2, else request again
-
Retrieve the selected car from the user input
-
selectCar() – Input should be within the size of vehicle list, else request again
-
getNewOdometerReading() – New odometer reading is used to calculate the oil change, tire rotation, power recharge etc.
Answer:
- Define the Type enum to represent different fuel types: GAS, DIESEL, ELECTRIC.
- Create a base class Vehicle with members for make, model, year, and odometer reading. Include getter methods for these attributes.
- Define pure virtual methods in the Vehicle class: getType(), checkTireRotation(), checkOilChange(), and checkBatteryCharge() for maintenance checks.
- Create three derived classes: GasCar, DieselCar, and ElectricCar, which inherit from the Vehicle class. Implement the virtual methods for each derived class based on the specific maintenance checks.
- Create an abstract class FuelVehicle that inherits from Vehicle and includes a getFuelType() method.
- Develop the Inventory class to manage a list of vehicles using a vector. Include methods for adding, listing, updating, and removing vehicles, as well as getting vehicle information and size.
- Implement a function getTypeString() in the Inventory class to convert the fuel type to a string for display.
- Create the main() function, which provides a menu for the user to add, update, list, or remove vehicles. It also includes options to check tire rotation, oil change, and battery charge.
- Inside the main() function, handle user input, and interact with the Inventory class to perform the selected actions.
- For each menu choice (e.g., check tire rotation, oil change, or battery charge), get user input to select the vehicle and display the appropriate maintenance advice.
- Ensure proper error handling, such as validating user input for vehicle selection.
- Compile and run the program, testing various functionalities and maintenance checks for different vehicle types..
Code:
#include
#include
enum Type {
GAS,
DIESEL,
ELECTRIC
};
class Vehicle {
protected:
std::string make;
std::string model;
int year;
double odometer;
public:
Vehicle(const std::string& make, const std::string& model, int year, double odometer)
: make(make), model(model), year(year), odometer(odometer) {}
const std::string& getMake() const { return make; }
const std::string& getModel() const { return model; }
int getYear() const { return year; }
double getOdometer() const { return odometer; }
virtual Type getType() = 0;
virtual void checkTireRotation() = 0;
virtual void checkOilChange() = 0;
virtual void checkBatteryCharge() = 0;
void getCarInformation() {
std::cout << "Make: " << make << std::endl;
std::cout << "Model: " << model << std::endl;
std::cout << "Year: " << year << std::endl;
std::cout << "Odometer Reading: " << odometer << " km" << std::endl;
}
};
class GasCar : public Vehicle {
public:
GasCar(const std::string& make, const std::string& model, int year, double odometer)
: Vehicle(make, model, year, odometer) {}
Type getType() override { return GAS; }
void checkTireRotation() override {
if (static_cast(odometer) % 50000 == 0) {
std::cout << "Tire rotation advised." << std::endl;
} else {
int remainder = static_cast(odometer) % 50000;
if (remainder >= 0) {
std::cout << "Tire rotation advised." << std::endl;
} else {
std::cout << "Tire rotation not required." << std::endl;
}
}
}
void checkOilChange() override {
if (static_cast(odometer) % 10000 == 0) {
std::cout << "Oil change advised." << std::endl;
} else {
std::cout << "No oil change required." << std::endl;
}
}
void checkBatteryCharge() override {
if (static_cast(odometer) % 400 == 0) {
std::cout << "Battery recharge advised." << std::endl;
} else {
std::cout << "No recharge required." << std::endl;
}
}
};
class DieselCar : public Vehicle {
public:
DieselCar(const std::string& make, const std::string& model, int year, double odometer)
: Vehicle(make, model, year, odometer) {}
Type getType() override { return DIESEL; }
void checkTireRotation() override {}
void checkOilChange() override {
if (static_cast(odometer) % 10000 == 0) {
std::cout << "Oil change advised." << std::endl;
} else {
std::cout << "No oil change required." << std::endl;
}
}
void checkBatteryCharge() override {
if (static_cast(odometer) % 400 == 0) {
std::cout << "Battery recharge advised." << std::endl;
} else {
std::cout << "No recharge required." << std::endl;
}
}
};
class ElectricCar : public Vehicle {
public:
ElectricCar(const std::string& make, const std::string& model, int year, double odometer)
: Vehicle(make, model, year, odometer) {}
Type getType() override { return ELECTRIC; }
void checkTireRotation() override {
if (static_cast(odometer) % 50000 == 0) {
std::cout << "Tire rotation advised." << std::endl;
} else {
int remainder = static_cast(odometer) % 50000;
if (remainder >= 0) {
std::cout << "Tire rotation advised." << std::endl;
} else {
std::cout << "Tire rotation not required." << std::endl;
}
}
}
void checkOilChange() override {
if (static_cast(odometer) % 10000 == 0) {
std::cout << "Oil change advised." << std::endl;
} else {
std::cout << "No oil change required." << std::endl;
}
}
void checkBatteryCharge() override {
if (static_cast(odometer) % 400 == 0) {
std::cout << "Battery recharge advised." << std::endl;
} else {
std::cout << "No recharge required." << std::endl;
}
}
};
class Inventory {
private:
std::vector<Vehicle*> vehicles;
public:
void addVehicle(Vehicle* vehicle) {
vehicles.push_back(vehicle);
}
size_t size() const {
return vehicles.size();
}
Vehicle* getVehicle(int index) {
if (index >= 0 && index < vehicles.size()) {
return vehicles[index];
}
return nullptr;
}
void listVehicles() {
for (size_t i = 0; i < vehicles.size(); i++) {
std::cout << "Vehicle " << i + 1 << std::endl;
vehicles[i]->getCarInformation();
std::cout << "Fuel Type: " << getTypeString(vehicles[i]->getType()) << std::endl;
std::cout << "Maintenance Checks:" << std::endl;
vehicles[i]->checkTireRotation();
vehicles[i]->checkOilChange();
vehicles[i]->checkBatteryCharge();
std::cout << "--------------------------" << std::endl;
}
}
void updateVehicle(int index, double newOdometer) {
if (index >= 0 && index < vehicles.size()) {
vehicles[index]->getCarInformation();
std::cout << "Fuel Type: " << getTypeString(vehicles[index]->getType()) << std::endl;
std::cout << "Updated Odometer Reading: " << newOdometer << " km" << std::endl;
std::cout << "Maintenance Checks:" << std::endl;
vehicles[index]->checkTireRotation();
vehicles[index]->checkOilChange();
vehicles[index]->checkBatteryCharge();
} else {
std::cout << "Invalid vehicle index." << std::endl;
}
}
void removeVehicle(int index) {
if (index >= 0 && index < vehicles.size()) {
delete vehicles[index];
vehicles.erase(vehicles.begin() + index);
std::cout << "Vehicle removed from inventory." << std::endl;
} else {
std::cout << "Invalid vehicle index." << std::endl;
}
}
static std::string getTypeString(Type type) {
switch (type) {
case GAS: return "Gas";
case DIESEL: return "Diesel";
case ELECTRIC: return "Electric";
default: return "Unknown";
}
}
};
int main() {
Inventory inventory;
while (true) {
std::cout << "Select an option:\n"
<< "0. Quit\n"
<< "1. List inventory\n"
<< "2. Add vehicle\n"
<< "3. Update vehicle\n"
<< "4. Remove vehicle\n"
<< "5. Check Tire Rotation\n"
<< "6. Check Oil Change\n"
<< "7. Check Battery Charge\n"
<< "Enter your choice: ";
int choice;
std::cin >> choice;
if (choice == 0) {
break;
}
if (choice == 1) {
inventory.listVehicles();
} else if (choice == 2) {
std::string make, model;
int year, fuelType;
double odometer;
Type type;
std::cout << "Enter make: ";
std::cin >> make;
std::cout << "Enter model: ";
std::cin >> model;
std::cout << "Enter year: ";
std::cin >> year;
std::cout << "Enter odometer reading: ";
std::cin >> odometer;
do {
std::cout << "Enter fuel type (0 for GAS, 1 for DIESEL, 2 for ELECTRIC): ";
std::cin >> fuelType;
} while (fuelType < 0 || fuelType > 2);
type = static_cast(fuelType);
Vehicle* vehicle = nullptr;
if (type == GAS) {
vehicle = new GasCar(make, model, year, odometer);
} else if (type == DIESEL) {
vehicle = new DieselCar(make, model, year, odometer);
} else if (type == ELECTRIC) {
vehicle = new ElectricCar(make, model, year, odometer);
}
if (vehicle) {
inventory.addVehicle(vehicle);
std::cout << "Vehicle added to inventory." << std::endl;
}
} else if (choice == 3) {
int index;
double newOdometer;
std::cout << "Enter the index of the vehicle to update: ";
std::cin >> index;
if (index < 1 || index > inventory.size()) {
std::cout << "Invalid vehicle index." << std::endl;
continue;
}
std::cout << "Enter the new odometer reading: ";
std::cin >> newOdometer;
inventory.updateVehicle(index - 1, newOdometer);
} else if (choice == 4) {
int index;
std::cout << "Enter the index of the vehicle to remove: ";
std::cin >> index;
if (index < 1 || index > inventory.size()) {
std::cout << "Invalid vehicle index." << std::endl;
continue;
}
inventory.removeVehicle(index - 1);
} else if (choice == 5) {
int index;
std::cout << "Enter the index of the vehicle to check tire rotation: ";
std::cin >> index;
if (index < 1 || index > inventory.size()) {
std::cout << "Invalid vehicle index." << std::endl;
continue;
}
std::cout << "Tire Rotation Check for Vehicle " << index << std::endl;
inventory.getVehicle(index - 1)->checkTireRotation();
} else if (choice == 6) {
int index;
std::cout << "Enter the index of the vehicle to check oil change: ";
std::cin >> index;
if (index < 1 || index > inventory.size()) {
std::cout << "Invalid vehicle index." << std::endl;
continue;
}
std::cout << "Oil Change Check for Vehicle " << index << std::endl;
inventory.getVehicle(index - 1)->checkOilChange();
} else if (choice == 7) {
int index;
std::cout << "Enter the index of the vehicle to check battery charge: ";
std::cin >> index;
if (index < 1 || index > inventory.size()) {
std::cout << "Invalid vehicle index." << std::endl;
continue;
}
std::cout << "Battery Charge Check for Vehicle " << index << std::endl;
inventory.getVehicle(index - 1)->checkBatteryCharge();
} else {
std::cout << "Invalid choice. Please try again." << std::endl;
}
}
return 0;
}
Output:




