Adam Mo
Adam Mo

Reputation: 75

C++ Overloading operator >> (input) doesn't change original

I'm trying to build a custom dictionary class with custom string and definition classes. While trying to overload the >> (input) I get some kind of a problem. when the function ends the dictionary sent to it doesn't change. attaching the code: This is the overloading:

istream& operator>>(istream& ip, Dictionary& var) {
    Definition temp;
    ip >> temp;
    var += temp;
    return ip;
}

and some other functions used in it:

Dictionary& Dictionary::operator+=(Definition& input) {
    if (!checkCopy(input))
    {
        Definition** temp;
        temp = new Definition*[numWords + 1];
        for (int i = 0; i < numWords; i++)
        {
            temp[i] = book[i];
        }
        numWords++;
        temp[numWords - 1] = &input;
        delete[] book;
        book = temp;
    }
    return *this;
}
Dictionary::Dictionary(Dictionary& input) {
    *this = input;
}
Dictionary& Dictionary::operator=(Dictionary& input) {
    if (numWords != 0)
        delete[] book;
    book = new Definition*[input.numWords];
    for (int i = 0; i < input.numWords; i++)
    {
        *this += *input.book[i];
    }
    return *this;
}

And the class itself:

class Dictionary
{
private:
    int numWords = 0;
    Definition** book;
public:
    Dictionary();
    ~Dictionary();
    Dictionary(Dictionary&);
    bool operator==(Dictionary&) const;
    Dictionary& operator=(Definition&);
    Dictionary& operator=(Dictionary&);
    friend ostream& operator<<(ostream&, const Dictionary&);
    friend istream& operator>>(istream&, Dictionary&);
    Dictionary& operator-=(int);
    Dictionary& operator+=(Definition&);
    bool checkCopy(Definition&);
    Definition& operator[](int); //left side brackets for input
    Definition operator[](int) const; //right side brackets for output
};

EDIT: here is also the overloading operator for definition input:

istream& operator>>(istream& ip, Definition& var)
{
    cout << "Please enter a word: " << endl;
    ip >> var.word;
    cout << "Please enter the number of definitions for this word: " << endl;
    int idx;
    cin >> idx;
    while (idx<0)
    {
        cout << "Error: number of definitions not possible. Please Try again: " << endl;
        cin.clear();
        cin.ignore(INT_MAX, '\n');
        cin >> idx;
    }
    cin.clear();
    cin.ignore(INT_MAX, '\n');
    String* temp = new String[idx];
    for (int i = 0; i < idx; i++) {
        cout << "Please enter the " << i + 1 << "th definition: " << endl;
        cin >> temp[i];
        var += temp[i];
    }
    var.sortDefinition();
    return ip;
}

Help is indeed needed.

Upvotes: 0

Views: 87

Answers (2)

Adam Mo
Adam Mo

Reputation: 75

There were 2 problems:

what Alexander said about the temporary variable. changed it to:

Dictionary& Dictionary::operator+=(Definition& input) {
    if (!checkCopy(input))
    {
        Definition** temp;
        temp = new Definition*[numWords + 1];
        temp[0] = new Definition[numWords];
        for (int i = 0; i < numWords; i++)
        {
            temp[i] = book[i];
        }
        temp[0][numWords] = input;
        delete[] book;
        book = temp;
        numWords++;
    }
    return *this;
}

The second was that in the Definition class when I tried to access the number of definitions in an object that wasn't created due to the double pointer:

Definition** temp;
temp = new Definition*[numWords + 1];

So I changed it so it won't access it but first build it.

Thanks for the help Alexander!

Upvotes: 0

You should really stick to std::vector and other collection types rather than juggling around with pointers and new/delete as you do here.

In your operator+= function you're copying the address of a temporary variable into your array:

temp[numWords - 1] = &input;

Once the calling function operator>> ends, this pointer is less than worthless, because the original object (Definition temp;) does not exist any longer. Therefore the behaviour of that code is undefined!

You might get around this by defining a copy c'tor for Definition and then changing above line to:

*temp[numWords - 1] = input;

Also in your assignment operator you're making use of the operator+= function. However, your numWords member is not set appropriately at this time, so operator+= will likely do the wrong thing. So add a line to the assignment operator like this:

if (numWords != 0)
{
    delete[] book;
    numWords = 0; // add this line
}

Upvotes: 1

Related Questions