Vehicle class is an abstract base class for ElectricVehicle and GasolineVehicle classes, and HybridVehicle class inherits from ElectricVehicle and GasolineVehicle.
I have two 'Vehicle':base class undefined errors in ElectricVehicle.h and GasolineVehicle.h. I know I am messing up the #include files somehow, but I'm having trouble figuring that out.
I tried removing the Vehicle.cpp in ElectricVehicle.cpp and GasolineVehicle.cpp and adding the Vehicle header file, but that came up with a bunch of other errors.
Vehicle.h
#pragma once
#ifndef Vehicle_h
#define Vehicle_h
class Vehicle {
    
public:
    // check here  // 4 lines
    float engineEfficiency;
    virtual float calculateRange() = 0;
    virtual float percentEnergyRemaining() = 0;
    virtual void drive(float) = 0;
    virtual ~Vehicle();
};
#endif
Vehicle.cpp
#pragma once
#include "Vehicle.h"
#include <iostream>
using namespace std;
Vehicle::~Vehicle() {
    cout << "In vehicle destructor" << endl;
}
ElectricVehicle.h
#pragma once
#include <iostream>
#ifndef ElectricVehicle_h
#define ElectricVehicle_h
class ElectricVehicle : virtual public Vehicle {
public:
    float maximumCharge;
    float currentCharge;
    float engineEfficiency;
public:
    ElectricVehicle(float max, float eff);
    float calculateRange();
    float percentEnergyRemaining();
    void drive(float km);
    ~ElectricVehicle();
};
#endif
ElecticVehicle.cpp
#pragma once
#include "Vehicle.cpp"
#include "ElectricVehicle.h"
using namespace std; 
ElectricVehicle::ElectricVehicle(float maxEnergy, float rating) {
    engineEfficiency = rating;
    maximumCharge = maxEnergy; 
    currentCharge = maxEnergy;
}
ElectricVehicle::~ElectricVehicle() {
    cout << "In Electric vehicle destructor" << endl;
}
float ElectricVehicle::calculateRange() {
    return (currentCharge * 100 / engineEfficiency);
}
float ElectricVehicle::percentEnergyRemaining() {
    return (currentCharge * 100.0f / maximumCharge);
}
void ElectricVehicle::drive(float km) {
    if (currentCharge < 0) {
        cout << "Your Car is out of energy";
        return;
    }
    currentCharge -= (km / 100) * engineEfficiency;
}
GasolineVehicle.cpp
#include "Vehicle.cpp"
#include "GasolineVehicle.h"
using namespace std; 
GasolineVehicle::GasolineVehicle(float maxEnergy, float rating) {       
    engineEfficiency = rating;
    maximumGasoline = maxEnergy;
    currentGasoline = maxEnergy;
}
GasolineVehicle::~GasolineVehicle() {
    cout << "In Gasoline vehicle destructor" << endl;
}
float GasolineVehicle::calculateRange() {
    return currentGasoline * 100 / engineEfficiency;
}
float GasolineVehicle::percentEnergyRemaining() {
    return (currentGasoline * 100.0f / maximumGasoline);
}
void GasolineVehicle::drive(float km) {
    if (currentGasoline < 0){
        cout << "Your Car is out of energy";
        return;
    }
    currentGasoline -= (km / 100) * engineEfficiency;
}
Gasoline.h
#pragma once
#include <iostream>
#ifndef GasolineVehicle_h
#define GasolineVehicle_h
class GasolineVehicle : virtual public Vehicle {
public:
    float maximumGasoline;
    float currentGasoline;
    float engineEfficiency;
    GasolineVehicle(float max, float eff);
    ~GasolineVehicle();
    float calculateRange();
    float percentEnergyRemaining();
    void drive(float km);
};
#endif
HybridVehicle.cpp
#pragma once
#include "ElectricVehicle.h"
#include "GasolineVehicle.h"
#include "HybridVehicle.h"
#include<iostream>
using namespace std;
// hybridvehicle constructor is calling its parent class constructors;
HybridVehicle::HybridVehicle(float maxGasoline, float gasefficiency, float maxcharge, float electricefficiency) :GasolineVehicle(maxGasoline, gasefficiency), ElectricVehicle(maxcharge, electricefficiency) {}
    
HybridVehicle::~HybridVehicle() {
    cout << "In Hybrid vehicle destructor" << endl;
}
// :: is scope resolution operator as both gasoline and electric vehicle classes having engine efficiency the compiler
// will be confused of which variable to take.. so we :: to remove ambuiguity
float HybridVehicle::calculateRange() {
    return (currentCharge / ElectricVehicle::engineEfficiency) * 100 + (currentGasoline / GasolineVehicle::engineEfficiency) * 100;
}
float HybridVehicle::percentEnergyRemaining() {
    return ((currentCharge + currentGasoline) / (maximumCharge + maximumGasoline)) * 100.0f;
}
void HybridVehicle::drive(float km) {
    if (currentGasoline + currentCharge < 0) {
        cout << "Your Car is out of energy";
        return;
    }
    else if (currentCharge > 0) {
        currentCharge -= (km / 100) * ElectricVehicle::engineEfficiency;
    }
    else
    {
        currentGasoline -= (km / 100) * GasolineVehicle::engineEfficiency;
    }
}
HybridVehicle.h
#pragma once
#ifndef HybridVehicle_h
#define HybridVehicle_h
class HybridVehicle: public GasolineVehicle, public ElectricVehicle {
public:
    HybridVehicle(float gMax, float gEff, float eMax, float eEff);
    ~HybridVehicle();
    float calculateRange();
    float percentEnergyRemaining();
    void drive(float km);
};
#endif
Week2.cpp
#pragma once
#include "Vehicle.cpp"
#include "HybridVehicle.cpp"
using namespace std;
Vehicle* testVehicle(Vehicle* pVehicle, const char* vehicleName) {
    cout << vehicleName << " s range is: " << pVehicle->calculateRange() << endl;
    pVehicle->drive(150);
    cout << vehicleName << " s energy left is: " << pVehicle->percentEnergyRemaining() << endl;
    cout << vehicleName << " s range is now: " << pVehicle->calculateRange() << endl;
    return pVehicle;
}
int main(int argc, char** argv)
{
    //50L of gas, 7.1 L/100km
    delete testVehicle(new GasolineVehicle(50, 7.1), "Corolla");
    //42 L of gas, 4.3 L/100km, 8.8kWh, 22 kWh/100km
    delete testVehicle((GasolineVehicle*)new HybridVehicle(42, 4.3, 8.8, 22.0), "Prius");
    //75 kWh, 16 kWh/100km
    delete testVehicle(new ElectricVehicle(75, 16), "Tesla 3");
    return 0;
}
 
    