了解运营商

Understanding Operators

我们的教授给了我们一个练习测试和答案,以帮助我们进行即将到来的测试。我不明白这段代码的答案是 135.

我明白 class 是什么,但我对运算符的工作方式感到困惑。对于 v{6},我理解对于对象 vint v 等于 13。我认为在 int main 中 (-v - v).print 中的第一个 -v 将首先在 return 2 * v 的运算符中进行评估,并且它将 return 26。然后我认为他们会被放在最后一个运算符

V operator-(int lop, const V& rop)
{
    return rop - lop;
}

但我认为情况并非如此。我已将此代码放入 Visual Studio 中以对其进行处理,但我不明白发生了什么。

#include <iostream>
using namespace std;

class V
{
    int v;

public:
    V(int a = 3, int b = 7) : v{a + b}
    {
    }

    void print()
    {
        cout << v;
    }

    V operator-(const V& rop) const
    {
        return (3 * v) + (2 * rop.v) + 3;
    }

    V operator-()
    {
        return 2 * v;
    }
};

V operator-(int lop, const V& rop)
{
    return rop - lop;
}

int main() 
{
    V v{6};
    (-v - v).print();

    return 0;  
}

哇,这是令人困惑的代码,有 re-used 变量名、奇怪的非常规操作等等。该代码特别难以理解,因为 V 可以从一个整数隐式构造,并且总是将 7 添加到该整数;即使使用调试器,我也花了一些时间才理解。请永远不要写这样的代码,即使是为了好玩!

main-v 的结果不是 int。它是一个从表达式 2 * v (=26) 隐式构造的 V 对象,结果是一个值为 33 (26+7) 的成员整数。

就好像你写的一样:

V operator-()
{
    return V(2 * v);
}

或者,由于默认参数:

V operator-()
{
    return V(2 * v, 7);
}

然后你拿这个新的 returned 对象并将它提供给成员 operator-(const V&);同样的故事也适用。它产生表达式 3*33 + 2*13 + 3,即 128;这再次用于构造一个新的 V(因为那是 return 类型!),所以加 7 得到 135.

operator-(int lop, const V& rop) 不会出现,因为您从未在 intV.

之间执行减法

-v 的结果不是 int,而是 V
因此,将使用 member-overloaded 减法。

这是等效的代码,没有运算符的语法糖,但具有 return 个值的显式转换:

class V
{
public:
    V(int a = 3, int b = 7) : v{a + b}
    {
    }

    void print()
    {
        cout << v;
    }

    V subtract(const V& rop) const
    {
        return V((3 * v) + (2 * rop.v) + 3);
    }

    V negate()
    {
        return V(2 * v);
    }
private:
    int v;
};


int main() 
{
    V v{6};
    (v.negate().subtract(v)).print();

    return 0;  
}