简体   繁体   English

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

[英]C++: Post ++ operator overload after an assignment operator

Please note, that this question relates to an assignment for school. 请注意,这个问题与学校作业有关。

We are building a custom Fraction class with most operators being overloaded. 我们正在构建一个自定义的Fraction类,其中大多数运算符都已过载。 Most of them are not giving me problems. 他们大多数没有给我带来麻烦。 However, this part of the driver is not working for me: 但是,驱动程序的这一部分不适用于我:

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";

What happens is that f2 gets assigned the value of f1++ and not pre-incremented f1, which is what the assert assumes should be there. 发生的情况是为f2分配了f1 ++的值,而不是预先递增的f1,这是断言假定应该存在的值。

My operator looks like: 我的运算符如下:

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

Now, I'm scratching my head over this because in my head the logic is that ++ has precedence over the assignment operator, so I'd have expected the asserts to test f1 and f2 with the same values for a post++ operation. 现在,我对此深思熟虑,因为在我的脑海中,逻辑是++优先于赋值运算符,因此,我期望断言使用post ++操作的相同值测试f1和f2。 For the ++pre overload, the assert values are equal to each other in the driver. 对于++ pre重载,驱动程序中的断言值彼此相等。

My question is, why should f2 take the pre-incremented value of f1, and how could I modify my operators to achieve this, or could this be an error from the prof? 我的问题是,为什么f2应该采用f1的预先增加的值,以及如何修改我的运算符以实现此目标,或者这可能是教授的错误?

Assignment operator: 分配运算符:

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

Post-increment returns a value before the increment. 后增量返回增量之前的值。 That is why when you see return *this in a postfix ++ or -- operator you should immediately know that the implementation is wrong. 这就是为什么当您在postfix ++--运算符中看到return *this ,应该立即知道实现错误的原因。

The correct sequence of actions is as follows: 正确的操作顺序如下:

  • Make a copy of *this 复制*this
  • Do the increment 做增量
  • Return the copy. 返回副本。

Assuming that your Fraction class has a properly functioning copy constructor, the fix is very easy: 假设您的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;
}

When you have problems with overloaded operators as in your example, it's often helpful to look behind the syntactic sugar and see what the calls "really" look like. 当您遇到如示例中的重载运算符问题时,回顾语法糖并查看“真正”的调用通常会很有帮助。

f2 = f1++;

This one actually translates as: 这实际上翻译为:

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

It's even clearer if you assume for one moment that these are really just ordinarily named functions: 如果您暂时假设它们实际上只是通常命名的函数,那就更清楚了:

f2.Assign(f1.PostIncrement());

Now it should be obvious what happens. 现在应该很清楚会发生什么。 Your PostIncrement function is called first, and its result is passed as an argument to Assign . 首先调用PostIncrement函数,并将其结果作为参数传递给Assign

There is nothing magic about overloaded operators. 重载运算符没有什么魔术。 They are just functions with special names. 它们只是具有特殊名称的函数。 There are no special rules for returning values or passing arguments. 对于返回值或传递参数没有特殊的规则。 Thus, 从而,

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

, imagined like this: ,像这样想象:

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

does exactly what you wrote: It increments itself, then returns itself. 完全符合您的写法:先递增,然后返回。

If you want the same post-increment semantics as the built-in types, then you have to implement those semantics manually . 如果您想要与内置类型相同的后递增语义,则必须手动实现这些语义 In your operator++(int) , create a temporary copy of *this first, then increment, then return the temporary copy. 在您的operator++(int) ,首先创建*this的临时副本,然后递增, 然后返回该临时副本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM