skip to Main Content

I’m a student who is learning C++ (especially the operator overloading part). During my study, I found the following code that uses operator overloading doesn’t make an expected output. At first, the code with which I have trouble is the…

#include <iostream>
using namespace std;

class Power {
    int kick;
    int punch;
public:
    Power(int kick = 0, int punch = 0) {
        this->kick = kick; this->punch = punch;
    }
    void show();
    Power operator << (int n); 
};

void Power::show() {
    cout << "kick=" << kick << ',' << "punch=" << punch << endl;
}


Power Power::operator <<(int n) {
    kick += n;
    punch += n;
    return *this; 
}

int main() {
    Power a(1, 2);
    a << 3 << 5 << 6; 
    a.show();
}

The overloaded operator << was designed for adding the integer to all member variables of the instance. I installed << operators three times in a single line such as a + 3 + 5 + 6. I expected the output will be kick=15,punch=16, but the console shows kick=4,punch=5 as a result of that code. It seems that only the first << operation works and the behind code doesn’t work at all as I expected like parallelly connected math operators.

I know this unexpected behavior of the suggested code will be simply fixed by adding &(reference) to the operator overloading like Power& operator << (int n); , but I can’t grasp why these make totally different outputs. When I utilized the debugging feature in Visual Studio, the calculated outputs since the second overloaded operation aren’t applied to the target a, but I couldn’t find more answers beyond just the behavior.

2

Answers


  1. Power Power::operator <<(int n) {
    

    This returns a copy of your Power object. This new object will be modified in further << operations. What you mean to do is modify the same object three times as you perform more << operations.

    You should do:

    Power& Power::operator <<(int n) {
    ...
    

    then, the same object would be returned, by reference.

    Login or Signup to reply.
  2. As you discovered, you need that & to return a reference of this.

    What really happens?

    a << 3
    

    creates a new Power object since you return Power instead of Power&.

    Let’s call that new object b. Then what happens next is:

    b << 5
    

    Again, that returns a new object of type Power. Let’s call this one c. Finally this happens:

    c << 6
    

    The expression returns c with the correct result, but you do not capture that value. You could do so with:

    c = a << 3 << 5 << 6;
    

    Then verify that c is what you expect:

    c.show();
    

    You could also capture b like so (since you’re learning, just don’t write such expressions, it’s very cryptic):

    c = (b = a << 3) << 5 << 6;
    

    Forgetting the & in an operator is a common mistake. Or rather, some operators return a copy (operator + (...)) and others are expected to return a reference (operator += (...)) and it’s often that we copy/paste and forget to tweak the return value and it looks like it works in most cases and when you daisy chain it starts failing in really strange ways…

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search