edo101
edo101

Reputation: 639

Operator Overload Confusion with custom Class

I am following this tutorial on operator overloading: https://www.geeksforgeeks.org/operator-overloading-c/

Code snippet:

class Complex {
private:
    int real, imag;
public:
    Complex(int r = 0, int i = 0) { real = r;   imag = i; }

    // This is automatically called when '+' is used with 
    // between two Complex objects 
    Complex operator + (Complex const& obj) {
        Complex res;
        res.real = real + obj.real;
        res.imag = imag + obj.imag;
        return res;
    }
    void print() { cout << real << " + i" << imag << endl; }
};

int main()
{
    Complex c1(10, 5), c2(2, 4);
    Complex c3 = c1 + c2;
    c3.print();
}

My question is, how does c++ know what to pass in to &obj and how does it know what to give to real and imag within the operator function? Like how does it know 10 for c1 goes to real and 2 for c2 goes to obj.real? It was never specified which object gets assigned to obj. Hell how does it even know to parse c1's values to real and imag within the operator function?

Upvotes: 0

Views: 537

Answers (1)

user10957435
user10957435

Reputation:

c1 is the object you're working with. That probably sounds confusing, so let me explain.

When you do this:

c1 + c2;

ignoring the return value for a second, that code is the same as doing this:

c1.operator+(c2);

So, c1 is the base object on which the operator is called. In the same way that c1.print() uses c1's values, calling the operator uses c1's values by default, so to speak.

Why is c1 called here and not c2? Like why isn't it the same as:

c2.operator+(c1);

This is because c1 is on the left hand side. If c2 were on the left hand side, like in the example c2+c1, then operator+() would get called on c2 instead.


So, in short (and other words), C++ uses operator+()(and similar operators) by calling operator+() in the following format:

left.operator+(right);

This allows you to use real and imag like you would in print() for the left side's member variables, and other.real and other.imag for the right side's variables.


So, in the comments you asked a couple more questions that I figure might take more than a comment or two to answer, but are worth answering. So, here goes.

So if you call that + function, it ignores the c3 which I actually assumed was what we were working with, and looks at the left and right hand side of the operation to know what to assign to each side?

Correct. As far as inside the function, operator+() only looks at the objects immediately beside it (in this case, c1 and c2) to perform the calculation.

I am surprised because c3 technically is what I am working with,

Ah, okay. Not for the calculation itself. Let's look at your operator+() closely again:

Complex operator + (Complex const& obj) {
    Complex res;
    res.real = real + obj.real;
    res.imag = imag + obj.imag;
    return res;
}

Here, you have a current object (which is where real and imag come from) and another object (which is where obj.real and obj.imag come from). It's these that make up c1 and c2. These are the numbers you are actually adding.

c3, on the other hand, is the result of this addition. If I have something like this:

4 + 3 = 7

The operation 4+3 will have a result: 7. That's what c3 is here. Well, technically, that's what res is here. By returning res, you're returning the result. And in the case of c3, it's setting it's value to the returned result of operator+() via the assignment (=) operator.

Secondly, why do I need to return res?

Already sort of covered that, but to be clear: res is the result of the operation. C++ wouldn't know how to get the result otherwise.

res is only a local variable, wouldn't it's data get destroyed once + is done, instead of it passing the summation data to real and imag?

You seem to be confusing returning by reference and returning by value. If you return a local variable by reference, absolutely. This will get destroyed. However, if you return by value, the result gets copied out almost by definition, so you're totally fine here in this example.

Upvotes: 1

Related Questions