LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   C++: Overloading overloaded operators (https://www.linuxquestions.org/questions/programming-9/c-overloading-overloaded-operators-921948/)

Aquarius_Girl 01-04-2012 03:14 AM

C++: Overloading overloaded operators
 
Code:

binaryOperators binaryOperators :: operator+ (const binaryOperators &right)
{
    return binaryOperators (*this + right.i);
}

binaryOperators operator+ (const binaryOperators &left, const binaryOperators &right)
{
    return binaryOperators (left.i + right.i);
}

int main ()
{
    binaryOperators obj (10);

    obj = 11 + obj;

    obj = obj + 11;

    return 0;
}

So, here the statement obj = 11 + obj; calls the function with explicit argument specification, and this one obj = obj + 11; calls the function which is the member of the class. Fine.

The problem is that second call results in an infinite loop.
What are the reasons and how to avoid that?

eSelix 01-04-2012 03:51 AM

Why
Code:

binaryOperators binaryOperators :: operator+ (const binaryOperators &right)
{
    return binaryOperators (*this + right.i);
}

and not
Code:

binaryOperators binaryOperators :: operator+ (const binaryOperators &right)
{
    return binaryOperators (this->i + right.i);
}


Aquarius_Girl 01-04-2012 03:53 AM

I get your point, but could you explain in detail why the previous call results in an infinite loop?

Proud 01-04-2012 06:26 AM

This.i not this? You're recursively calling object + thing's value, not object's value + thing's value?

johnsfine 01-04-2012 07:25 AM

Quote:

Originally Posted by Anisha Kaul (Post 4565570)
I get your point, but could you explain in detail why the previous call results in an infinite loop?

If you got that point, you wouldn't still be asking that question. *this + right.i is a recursive call to the function containing it (using an implicit call to the constructor to turn right.i back into an object of type binaryOperators).

In addition, your choice of two versions of operator+ doesn't make sense. The first is a non const member function, so it will cover all the cases where the left operand is a non const binaryOperators object. The second is not a member function but takes const binaryOperators objects for left operand.

Why would you want that second function and why would you want the first one to only take non const left operands?

The typical reason for a non member version of operator+ is to take a left operand type that is not a object of the class you are working on.

eSelix 01-04-2012 07:51 AM

I think that Anisha ask why compiler not warn about ambiguity between these two functions, when calling
Code:

binaryOperators + i_casted_for_binaryOperators
The first operator+ (class member) is something like
Code:

binaryOperators operator+ (binaryOperators left, const binaryOperators &right)
which probably for compiler is more appropriate then the second, and choose that version. But this is only my guess.

johnsfine 01-04-2012 08:16 AM

Quote:

Originally Posted by eSelix (Post 4565749)
I think that Anisha ask why compiler not warn about ambiguity between these two functions

I don't think Anisha was asking that. But since you are effectively asking it, I'll explain:

There is no ambiguity because one definition required a non const left operand and the other takes a const left operand.

When the left operand actually is const, the compiler can only use the definition that takes a const left operand. No hint of ambiguity there.

When the left operand is non const, a definition that takes a const left operand could be used (some ambiguity there) but the definition that takes a non const left operand is more specific. The ambiguity is resolved when one definition is more specific than the other.

Next consider the statement
Code:

    obj = 11 + obj;
The left operand is a const int and the right operand is a non const binaryOperators. No operator+ takes that pair of inputs, so the compiler must find implicit casts.

When you implicitly cast an integer to a binaryOperators, the result is a temporary object, and a temporary object passed by reference to a function is const. So even if the int had not been const, the binaryOperators object it becomes would be const.

The fact that the right operand is non const makes no difference because both operator+ definitions take only const right hand operands (so neither definition is a less specific fit to the right hand operand).

Only one definition fits the const left hand operand, so that definition is used.


All times are GMT -5. The time now is 10:39 PM.