Why does returning *this result in an infinite loop?

我的未来我决定 提交于 2019-12-23 19:03:30

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!