如何在不修改 C++ 中的 LHS 参数的情况下实现 `+` 运算符?

How to implement `+` operator without modifying the LHS argument in C++?

我正在尝试了解重载运算符在 C++ 中的工作原理。我设法弄清楚如何实现 +== 运算符,但我正在努力使用 + 运算符。编译器告诉我运算符只能接受一个或两个参数。我似乎不知道如何正确 return 结果。

我可以作为参数的对象是运算符的 LHS 和 RHS,但在我看来,我必须创建 class 的第三个实例以某种方式存储和 return 结果。我认为 + 操作员不应该自己修改 LHS 或 RHS。

此外,在方法中创建新实例将不起作用,因为该对象将在方法完成后被删除。

那么如何正确地将结果存储在新实例中?

这是我到目前为止尝试过的:

#include <iostream>

class smallclass
{
public:
    smallclass();
    smallclass(int x);

    smallclass& operator+=(smallclass&y);
    smallclass& operator=(smallclass& y);
    smallclass& operator+(smallclass& y);
    int a;

};

smallclass::smallclass()
{

}

smallclass::smallclass(int x)
{
    this->a = x;
}


smallclass& smallclass::operator+=(smallclass&y)
{
    this->a += y.a;

    return *this;
}

smallclass& smallclass::operator=(smallclass& y)
{
    int value = y.a;
    this->a = value;
    return *this;
}


smallclass& smallclass::operator+(smallclass& y)
{
    int value = y.a;
    this->a += value;

    return *this;
}


int main()
{
    smallclass a = smallclass(5);
    smallclass b = smallclass(6);

    std::cout << a.a << std::endl;
    std::cout << b.a << std::endl;
    // a = 5
    // b = 6

    a += b;

    std::cout << a.a << std::endl;
    std::cout << b.a << std::endl;
    // a = 11
    // b = 6

    a = b;

    std::cout << a.a << std::endl;
    std::cout << b.a << std::endl;
    // a = 6
    // b = 6

    smallclass c;

    c = a + b;

    std::cout << a.a << std::endl;
    std::cout << b.a << std::endl;
    std::cout << c.a << std::endl;
    // a = 12 should be 6
    // b = 6
    // c = 12

    return 0;

}

您正在 returning *this 来自 operator+。您应该 return 一个包含新结果的对象。通过 returning *this 你是说 x + y 的结果总是 x,这是不正确的。结果是一个新值,不同于 xy。请注意 return 类型不应是引用,因为 returned 值不引用任何现有实例。

smallclass smallclass::operator+(smallclass& y)
{
    smallclass result;
    result.a = this->a + y.a;
    return result;
}

您还应该阅读 const 正确性。通过使 y 成为 const 引用,您向用户保证您的操作员不会修改 y。使整个成员函数const也是如此。它向您的 class 的用户保证操作员不会修改 this。没有这些 const,您将无法在 const 个实例中使用您的运算符。

smallclass smallclass::operator+(const smallclass& y) const
{
    smallclass result;
    result.a = this->a + y.a;
    return result;
}

一种更惯用的方法是根据 operator+= 和复制构造函数来实现 operator+。这样,您就不必重复自己。

smallclass smallclass::operator+(const smallclass& y) const
{
    smallclass result(*this);
    result += y;
    return result;
}

您可以为许多操作员执行此操作。值得注意的是,比较运算符都可以仅根据两个基本比较来实现,例如 operator==operator<.

实现operator+的规范版本是这样的:

friend smallclass operator+ (smallclass op1, smallclass const& op2) {
   op1 += op2;
   return op1;
}

这种方法在可能的情况下利用了复制省略,还利用了 operator+= 的现有实现。

如果您想禁止左侧的自动转换,您可以使用以下版本进行交换加法:

smallclass operator+ (smallclass rhs) const {
    rhs += *this;
    return rhs;
}

如果加法不可交换,你会使用

smallclass operator+ (smallclass const& rhs) const {
    return smallclass(*this) += rhs;
}

(最后一版不能完全省略一份)