0

So i have this code:

vehicle *v1=&c;
std::cout<<"Car: "<<endl;
v1->input(cin);

Vehicle is a base class and Car is the derived one. They both share a virtual function input. The problem is that whenever i call this method, the program can only fill the base part. Here is the code for the input. For the base class:

istream& vehicle::input(istream& is) {

    char buffer[100];
    is.getline(buffer,100);
    set_type(buffer);
    is.getline(buffer,100);
    set_brand(buffer);
    is.clear();
    return is;
}

And for car, derived class:

istream& car::input(istream& is) {

    vehicle::input(is);
    char buffer[100];
    is.getline(buffer,100);
    set_alim(buffer);
    is.clear();
    return is;
}

I also tried deleting the call vehicle::input(is); and the program doesn't do anything. Supposedly it cannot recognize the virtual method. How do I fix this?

As required:

class vehicle {
friend ostream& operator<<(ostream&, const vehicle&);
friend istream& operator>>(istream&, vehicle&);
protected:
    char* type;
    char* brand;
public:
    //constructors
    void set_type(const char* t) {
        delete [] type;
        type=new char(strlen(t)+1);
        strcpy(type,t);
    }
    void set_brand(const char* t) {
        delete [] brand;
        brand=new char(strlen(t)+1);
        strcpy(brand,t);
    }

    virtual istream& input(istream&);
};

class car:public vehicle {
friend ostream& operator<<(ostream&, const car&);
friend istream& operator>>(istream&, car&);
private:
    char* alim;
public:
    //constructors
    void set_alim(const char* a) {
        delete [] alim;
        alim=new char(strlen(a)+1);
        strcpy(alim,a);
    }

    virtual istream& input(istream&);
};

EDIT: I found the bug, the problem was not using is.ignore() even though if you create a new project and build the code exactly as i did, it works just fine

Dave2222
  • 57
  • 4
  • Please [edit] your question to include a [mcve] that shows the class definitions of `vehicle` and `car`, as well as how you declare `c` in your first example. Otherwise, as it's currently written, we can't can't rule out errors in the code you haven't shown. – alter_igel Apr 18 '19 at 22:47
  • Something tells me your setters aren't written properly. – chris Apr 18 '19 at 22:52
  • 1
    Well. That edit derails my shot in the dark. Turns out we got a typo. `alim=new char(strlen(a)+1);` should be `alim=new char[strlen(a)+1];`. Note the different outer brackets. The first creates exactly one `char` set to have `strlen(a)+1` as it's value. The second one makes an array of `char` of size `strlen(a)+1` – user4581301 Apr 18 '19 at 23:00
  • 1
    It looks like `delete[]` is being used on uninitialized pointers, too. – chris Apr 18 '19 at 23:01
  • @user4581301 I wish that was the fix, unfortunately the problem still exists.. – Dave2222 Apr 18 '19 at 23:02
  • @chris what do you mean? – Dave2222 Apr 18 '19 at 23:03
  • `char* type;` leaves `type` pointing who knows where, so when `delete [] type;` runs, it's hard to say what the program tries to `delete`. It almost certainly won't be something it can `delete`. Use `char* type = NULL;` instead. – user4581301 Apr 18 '19 at 23:06
  • @user4581301 they always taught me like this, i would use constructors to initialize them – Dave2222 Apr 18 '19 at 23:08
  • Why no `std::string`? Your code could be functionally identical, much safer, and half as long. – alter_igel Apr 18 '19 at 23:08
  • @Dave2222 If I may ask, who are "they" who taught you? It seems like "they" are teaching very outdated and unsafe C++ style. You should consider getting a [good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) if you want a better experience – alter_igel Apr 18 '19 at 23:09
  • If you initialize `type` in the constructor, you should be safe. Better add the constructors to the question. It's partially because of this kind of back-and-forth guess-counter-guess that [mcve]s are required. The main reason for the MCVE is it's a powerful debugging technique. If you apply it before asking a question most of the time you will find the bug and fix it before asking the question. Everybody wins! – user4581301 Apr 18 '19 at 23:11
  • I am getting myself ready for the programming exam, so I am programming to the liking of my prof – Dave2222 Apr 18 '19 at 23:11
  • @user4581301 i did it in other programs but for the output (print) function, and that works just as intended – Dave2222 Apr 18 '19 at 23:13
  • In modern C++ there are a bunch of ways to initialize a member variable. You can do it at the definition, `char* type = NULL;`, you can do it in [the initialzer list](https://en.cppreference.com/w/cpp/language/initializer_list), sometimes you can use [aggregate initialization](https://en.cppreference.com/w/cpp/language/aggregate_initialization) (not this time though). if you `type = NULL;` inside the body of the construxctor, thats assignment and not initialization, but it'll work fine. Anyway, [mcve] or we're kinda out of guesses. – user4581301 Apr 18 '19 at 23:17
  • @Dave2222, Forgive me. It looked like you labelled your setters as constructors in the code you showed. – chris Apr 18 '19 at 23:17
  • @chris no big deal bud. – Dave2222 Apr 18 '19 at 23:23
  • i have a huge program, i cannot add the entire program so i gotta add some pieces – Dave2222 Apr 18 '19 at 23:24
  • Go back and look at the bit about the [mcve] again. It is a sort of divide and conquer attack. You don't post all of the code, you back up your code and then rip out everything that isn't necessary to reproduce the bug, but still reproduces the bug (as in it compiles and runs and does whatever bad behaviour the full program does). If you follow it all the way to the end, you wind up with a small program that is nothing but the bug. The beauty is you almost never have to go the whole way because as the program gets smaller, it's harder for the bug to hide. – user4581301 Apr 18 '19 at 23:32

0 Answers0