1

In my C++ I would like to print out cars and lorrys (derived from the vehicle class). Here are the definitions of the classes:

class Vehicle
{
    int speed;
    int entryTime;
    int currentPositionInLane;
    int minimumFollowingDistance;
public:

    virtual void print() const {
        std::cout << "speed: " << speed << std::endl;
        std::cout << "entryTime: " << entryTime << std::endl;
        std::cout << "currentPositionInLane: " << currentPositionInLane << std::endl;
        std::cout << "minimumFollowingDistance: " << minimumFollowingDistance << std::endl;
    }
};
 
class Car : public Vehicle
{
    int currentLane;
public:
    Car(int, int, int, int, int);
    void pass(const Vehicle&);
    void print() const {
        Vehicle::print();
        std::cout << "currentLane: " << currentLane << std::endl;
    }
};
class Lorry: public Vehicle
{
public:
    Lorry(int speed, int entryTime, int currentPositionInLane, int minimumFollowingDistance): Vehicle(speed, entryTime, currentPositionInLane, minimumFollowingDistance){}
};

class Road
{
    double updateFrequency;
    double currentTime;
    Vehicle* vehicles;
    int vehicleCount;
public:
    Road();
    void update();
    bool checkIfFinished();
    void checkForUserInterrupt();
    void saveToFile();
    bool setCurrentTime(double);
    bool setUpdateFrequency(double);
    void addVehicle(const Vehicle& vehicle);

    void print();
};

The print method of the Road class:

void Road::print() {
std::cout << "updateFrequency: " << updateFrequency <<std::endl;
std::cout << "currentTime: " << currentTime << std::endl;
std::cout << std::endl << "The vehicles on the road: " << std::endl << std::endl;
for (int i = 0; i < vehicleCount; i++)
{
    vehicles[i].print();
    std::cout << std::endl;
}

}

My problem is that despite the print method of the base class being virtual, the print method of the car class never gets called. As far as I understand the problem is object slicing. That's why I pass the Lorry or Car as a Vehicle reference in the addVehicle method, however that doesn't fix the issue. I suspect that the problem is in the addVehicle function and somehow I should overwrite the = operator:

void Road::addVehicle(const Vehicle& vehicle) {
if (vehicles == nullptr) {
    vehicles = new Vehicle[1];
    vehicles[0] = vehicle;
    vehicleCount = 1;
}
else {
    Vehicle* temp = new Vehicle[vehicleCount + 1];
    for (int i = 0; i < vehicleCount; i++) {
        temp[i] = vehicles[i];
    }
    temp[vehicleCount] = vehicle; // I think this is the line causing the issue
    vehicleCount++;
    delete[] vehicles;
    vehicles = temp;
}

}

jdsflk
  • 417
  • 9
  • 23
  • 5
    Problem is `Vehicle* vehicles;` used as an array. When you have polymorphism you can't use value ob base class, it must be array of pointers. So replace this with: `std::vector> vehicles;` (do not use `new`/`delete` explicitly let smart pointers take a responsibility for memory management). – Marek R May 12 '23 at 15:24
  • 1
    BTW when I see what properties `Vehicle` I see you should avoid use polymorphism. I see that all thing in your code can be modeled by data (values) not by types. This way your program will be faster since polymorphism overhead is quite big in your simulation. – Marek R May 12 '23 at 15:31
  • Your `Vehicle` class does not have a virtual destructor, thus is not safe to be used in a polymorphic manner. You need to add `virtual ~Vehicle() = default;` to the class. – PaulMcKenzie May 12 '23 at 15:45

0 Answers0