问题
class binaryOperators
{
public:
int i;
binaryOperators (int tempI = 0)
{
i = tempI;
}
binaryOperators operator+ (const binaryOperators &right);
};
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?
回答1:
The conversion from binaryOperators::i
(of type int
) to binaryOperators
is implicit (i.e. not declared explicit
).
return binaryOperators (*this + right.i); // (1)
binaryOperators binaryOperators :: operator+ (const binaryOperators &right); // (2)
binaryOperators operator+ (const binaryOperators &left, const binaryOperators &right); // (3)
In the line (1) two operator+
functions can be considered: The member version (2) and the free version (3). Since the LHS is of type binaryOperators&
, the member version is applicable and preferred. Its argument is of type const binaryOperators &
, and the argument given in line (1) is of type int
, so the compiler tries to convert int
to const binaryOperators &
.
Since there is a non-explicit
constructor with one argument, it is used as an implicit conversion from int
to const binaryOperators &
. Now we have two operands of types binaryOperators&
and const binaryOperators &
, the operator+
in (2) can be called, and we are right where we started.
Lesson: Don't over-do implicit conversions.
回答2:
The problem is in the statement:
return binaryOperators (*this + right.i);
*this
is of type binaryOperators, so an operator is needed with a left-hand-side argument of type (or reference to) binaryOperators.
The possibly matching operators are the two you provide, so the right-hand-side argument needs to be of type const binaryOperators &
. Thus the right.i
is converted to a temporary binaryOperators using the appropriate constructor.
As a result, the member operator ends up calling itself, which calls itself, calling itself, etc., resulting in infinite recursion (what you see as an infinite loop).
You can probably fix this here by using:
return binaryOperators (this->i + right.i);
来源:https://stackoverflow.com/questions/8724845/why-does-returning-this-result-in-an-infinite-loop