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

时间:2017-12-13 21:26:39

标签: c++ operators

我试图了解重载运算符如何在C ++中工作。我设法弄清楚如何实施+==运算符,但我正在努力使用+运算符。编译器告诉我操作符只能接受一个或两个参数。我似乎无法弄清楚如何正确地返回结果。

我可以作为参数的对象是运算符的LHS和RHS,但在我看来,我必须以某种方式创建类的第三个实例来存储和返回结果。我不认为+运算符应该自己修改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;

}

2 个答案:

答案 0 :(得分:4)

您将从*this返回operator+。您应该返回包含新结果的对象。返回*this即表示x + y的结果始终是x,这是不正确的。结果是一个新值,与xy不同。请注意,返回类型不应该是引用,因为返回的值不会引用任何现有实例。

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

您还应该阅读const正确性。通过y const引用,您可以向用户保证您的运营商不会修改y。关于使整个成员函数const也是如此。它向您的班级用户保证,操作员不会修改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<

答案 1 :(得分:3)

实施operator+的规范版本是:

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

此方法尽可能利用copy-elision,并利用operator+=的现有实现。

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

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

如果添加不是可交换的,则使用

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

(最后一个版本不能完全忽略一个副本)。