#display function not calling the correct virtual function

1 messages · Page 1 of 1 (latest)

chrome bolt
#

Good morning! I'm finishing up an assignment, but I'm stuck on two things.

First image is a text comparison (LHS shows correct_output.txt and RHS shows student_output.txt)
 
As the text comparison shows, I'm having an issue:
 
It seems that my Racecars are using Car::topSpeed() instead of Racecar::topSpeed() despite the fact that I've declared Car::topSpeed() as virtual, inside the Car::display function.
 
Any advice on how to troubleshoot this would be greatly appreciated!! T_T

atomic nexusBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question run !howto ask.

#

@chrome bolt

Screenshots!

Your message appears to contain screenshots but no code. Please send code and error messages in text instead of screenshots if applicable!

chrome bolt
#

Please let me know if you'd like me to share details of the code!

main wing
#

Don't send screenshots

#

copy and paste both classes in and methods and i will have a look

#

and also where you are calling it

chrome bolt
#

Awesome, just one moment please!

atomic nexusBOT
#
How to Format Code on Discord
Markup

```cpp
int main() {}
```

Result
int main() {} ```
chrome bolt
#

sorry i'm just trying to find the relevant parts, but would you like the whole files?

#

@main wing

main wing
#

the class's and the top speed methods

#

and where it's called and the object is created

chrome bolt
#

so my issue as you understand is with the wrong topSpeed() being called (I want it to use Racecar::topSpeed() not Car::topSpeed()) in this display function, in Car.cpp:

void Car::display(ostream& out) const {
    out << "| "  << right << setw(10) << m_maker << " | ";
    out << left << setw(6) << condition() << " | ";
    out << fixed << setprecision(2) << setw(6) << topSpeed() << " |";
}

my Car::topSpeed is as follows (Car.h and Car.cpp respectively):

virtual double topSpeed() const;


double Car::topSpeed() const {
    return m_topSpeed;
}

my Racecar::topSpeed() is:

double Racecar::topSpeed() const {
    return Car::topSpeed() * (1 + m_booster);
}
#

i think this is all the relevant parts @main wing

#

for refernce, these are the Car.h and Racecar.h, respectively:

#ifndef SDDS_CAR_H
#define SDDS_CAR_H

#include "Vehicle.h"

namespace sdds {
    class Car : public Vehicle {
        std::string m_maker{};
        std::string m_condition{};
        double m_topSpeed{};
    public:
        Car() {};
        Car(std::istream&);
        std::string condition() const;
        virtual double topSpeed() const;
        void display(std::ostream&) const;
    };

    std::string trim(const std::string& str);
    std::string splitAndTrim(std::string& str, const char delim);
}
#endif //SDDS_CAR_H

#ifndef SDDS_RACECAR_H
#define SDDS_RACECAR_H

#include "Car.h"

namespace sdds {
    class Racecar : public Car {
        double m_booster{};
    public:
        Racecar() {};
        Racecar(std::istream& in);
        void display(std::ostream& out) const;
        double topSpeed() const;
    };
}

#endif //SDDS_RACECAR_H
main wing
#

Show me where you create the racecar object

#

that is then printed

chrome bolt
#

so Racecar is created first here, once the "tag" is read and is either "r" or "R" ("c" or "C" is for a normal Car):

#include <sstream>
#include "Utilities.h"
#include "Racecar.h"

using namespace std;

namespace sdds {
    Vehicle* createInstance(std::istream& in) {
        Vehicle* vehicle{};
        string line{};
        string tag{};

        getline(in, line);
        stringstream ss(line);

        getline(ss, tag, ',');
        tag = trim(tag);

        if (tag != "") {
            if (tag == "c" || tag == "C") {
                vehicle = new Car(ss);
            }
            else if (tag == "r" || tag == "R") {
                vehicle = new Racecar(ss);
            }
            else {
                string message{};
                message = "Unrecognized record type: [" + tag + "]";
                throw string(message);
            }
        }

        return vehicle;
    }
}
#

these are the Car and Racecar constructors, respectively:

Car::Car(istream& is) {
        string line;

        getline(is, line);

        m_maker = splitAndTrim(line, ',');

        string conditionStr = splitAndTrim(line, ',');

        if (conditionStr == "") {
            m_condition = "new";
        }
        else {
            char condition = conditionStr[0];

            switch (condition) {
            case 'n':
                m_condition = "new";
                break;
            case 'u':
                m_condition = "used";
                break;
            case 'b':
                m_condition = "broken";
                break;
            default:
                throw string("Invalid record!");
            }
        }

        try {
            m_topSpeed = stod(trim(line));
        }
        catch (...) {
            throw string("Invalid record!");
        }
    }

Racecar::Racecar(istream& in) : Car(in) {
        if (in.peek() == ',') {
            in.ignore();
        }
        in >> m_booster;
    }
main wing
#

Can you use a debugger to check this?

chrome bolt
#

i wish i knew how to debug with input txt files ...

#

would it make things easier if i were to share a github link to the repo?

main wing
#

yeah'

chrome bolt
#

just one moment, pushing to git

#

just for reference, i understand screenshots can be useless but this screenshot shows the correct vs my output:

#

(all the prices are wrong for the "*", which are the Racecars, which should use the m_booster multipler to the m_topSpeed)

#

(and Porsche is missing for some reason, but i guess that's a different issue)

#

omg ... or i think the issue might actually be that the m_booster is not being initialized properly in the Racecar constructor ...

#

bc i just tried adding:

"cout << "TESTING m_booster:" << m_booster << endl;

to:

Racecar::Racecar(istream& in) : Car(in) {
    if (in.peek() == ',') {
        in.ignore();
    }
    in >> m_booster;
    cout << "TESTING m_booster:" << m_booster << endl;
}

and each m_booster outputs a value of 0.00 ...

main wing
chrome bolt
#

I see, so i assume the issue is with Racecar constructor?

main wing
#

same fo the jaguar

chrome bolt
#

holy moly thank you sir, i have resolved the issue

#

i can sleep now

#

!solved