C ++:赋值运算符后的Post ++运算符重载

时间:2014-07-05 10:44:44

标签: c++

请注意,这个问题与学校的作业有关。

我们正在构建一个自定义Fraction类,大多数运算符都被重载。他们中的大多数都没有给我带来麻烦。但是,这部分驱动程序对我不起作用:

cout << "testing post++ with f2 = f1++;" << '\n';
f2 = f1++;
cout << "f1 : " << f1 << '\n';
cout << "f2 : " << f2 << '\n';
assert(f1 == Fraction(6));
assert(f2 == Fraction(5));
cout << "ok\n\n";

f2被赋予了f1 ++的值,而不是预先递增的f1,这是断言假设的那个。

我的操作符如下:

Fraction Fraction::operator++(int a)
{
    numer = (numer + denom);
    normalize();
    return *this;
}

现在,我正在摸不着头脑,因为在我的脑海中,逻辑是++优先于赋值运算符,所以我希望断言用post ++测试f1和f2的值相同操作。对于++ pre重载,断言值在驱动程序中彼此相等。

我的问题是,为什么f2应该采用f1的预递增值,以及如何修改我的运算符来实现这一点,或者这可能是教授的错误?

作业运营商:

Fraction& Fraction::operator=(const Fraction &rhs) {
    numer = rhs.getNumer();
    denom = rhs.getDenom();
    return *this;
}

2 个答案:

答案 0 :(得分:2)

后增量在增量之前返回值。这就是为什么当您在后缀return *this++运算符中看到--时,您应该立即知道实现是错误的。

正确的行动顺序如下:

  • 制作*this
  • 的副本
  • 执行增量
  • 退回副本。

假设您的Fraction类具有正常运行的复制构造函数,则修复非常简单:

Fraction Fraction::operator++(int a)
{
    Fraction res(*this);
    // The following two lines are most likely shared with the prefix ++
    // A common trick is to call ++*this here, to avoid code duplication.
    numer = (numer + denom);
    normalize();
    return res;
}

答案 1 :(得分:2)

当您在示例中遇到重载运算符问题时,查看语法糖并查看“真正”调用的内容通常会有所帮助。

f2 = f1++;

这个实际上翻译为:

f2.operator=(f1.operator++(0));

如果你暂时假设这些只是通常命名的函数,那就更清楚了:

f2.Assign(f1.PostIncrement());

现在应该很清楚会发生什么。首先调用PostIncrement函数,并将其结果作为参数传递给Assign

重载运算符没有什么神奇之处。它们只是具有特殊名称的函数。返回值或传递参数没有特殊规则。因此,

Fraction Fraction::operator++(int a)
{
    numer = (numer + denom);
    normalize();
    return *this;
}

,想像这样:

Fraction Fraction::PostIncrement()
{
    numer = (numer + denom);
    normalize();
    return *this;
}

完全按照你所写的内容进行:它会自行递增,然后自行返回。

如果您想要与内置类型相同的后增量语义,则必须手动实现这些语义。在operator++(int)中,首先创建*this的临时副本,然后增加,然后返回临时副本。