简体   繁体   English

C ++运算符重载无法按预期工作

[英]c++ operator overloading not working as expected

Here is the whole class (copy/paste should work): 这是整个课程(复制/粘贴应该可以):

#include <cstdio>
#include <iostream>
using namespace std;

class Rational
{
    int _n = 0;
    int _d = 1;
public:
    Rational (int numerator = 0, int denominator = 1) : _n(numerator), _d(denominator) {};
    Rational (const Rational & rhs) : _n(rhs._n), _d(rhs._d) {};
    ~Rational();
    int numerator() const {
        return _n;
    };
    int denominator() const {
        return _d;
    };
    Rational & operator = (const Rational &);

};

Rational operator + (const Rational & lhs, const Rational & rhs)
{
    return ((lhs.numerator() * rhs.denominator()) + (lhs.denominator() * rhs.numerator()), lhs.denominator() * rhs.denominator());
}

Rational::~Rational()
{
    _n = 0;
    _d = 1;
}

std::ostream & operator << (std::ostream & o, const Rational & r)
{
    if (r.denominator() == 1) {
        return o << r.numerator();
    } else {
        return o << r.numerator() << '/' << r.denominator();
    }
}


int main()
{
    Rational a = 7;
    cout << "a is: " << a << endl;

    Rational b(5,3);
    cout << "b is: " << b << endl;

    cout << a << " + " << b << " = " << a + b << endl;
    cout << 14 << " + " << b << " = " << 14 + b << endl << endl;

    return 0;
}

I want to use non-member operator overload. 我想使用非成员运算符重载。 Code compiles but it displays wrong results. 代码会编译,但显示错误的结果。 The last two lines should display: 最后两行应显示:

7 + 5/3 = 26/3 7 + 5/3 = 26/3

14 + 5/3 = 47/3 14 + 5/3 = 47/3

but instead displays: 但改为显示:

7 + 5/3 = 3 7 + 5/3 = 3

14 + 5/3 = 3 14 + 5/3 = 3

The problem is most likely this: 问题很可能是这样的:

Rational operator + (const Rational & lhs, const Rational & rhs)
{
    return ((lhs.numerator() * rhs.denominator()) + (lhs.denominator() * rhs.numerator()), lhs.denominator() * rhs.denominator());
}

because it works properly if I change it to create object first and then return: 因为如果我先将其更改为创建对象然后返回,它将正常工作:

Rational operator + (const Rational & lhs, const Rational & rhs)
{
    Rational r((lhs.numerator() * rhs.denominator()) + (lhs.denominator() * rhs.numerator()), lhs.denominator() * rhs.denominator());
    return r;
}

I would expect implicit conversion and both solutions give the same results. 我希望隐式转换,并且两种解决方案都能得到相同的结果。 Could someone explain to me what is the difference here? 有人可以告诉我这里有什么区别吗?

return statement contains comma operator invocation discarding result of first expression (that was supposed to be numerator) and invoking constructor with just one paramter. return语句包含逗号运算符调用,该运算符丢弃第一个表达式(应该是分子)的结果,并仅使用一个参数来调用构造函数。 You should use proper initialization syntax: 您应该使用正确的初始化语法:

return Rational
(
    (lhs.numerator() * rhs.denominator()) + (lhs.denominator() * rhs.numerator())
,   lhs.denominator() * rhs.denominator()
);

or 要么

return
{
    (lhs.numerator() * rhs.denominator()) + (lhs.denominator() * rhs.numerator())
,   lhs.denominator() * rhs.denominator()
};

or (better) 或更好)

return Rational
{
    (lhs.numerator() * rhs.denominator()) + (lhs.denominator() * rhs.numerator())
,   lhs.denominator() * rhs.denominator()
};

This line causes your bug: 这行会导致您的错误:

return ((lhs.numerator() * rhs.denominator()) + (lhs.denominator() * rhs.numerator()), lhs.denominator() * rhs.denominator());

The problem is that it gets evaluated as a whole, which gives you an integer. 问题是它被整体评估,为您提供一个整数。 This integer is then fed to the implicitly invoked constructor of your Rational class. 然后,此整数将馈送到Rational类的隐式调用的构造函数。 Note that this line uses the comma-operator. 请注意,此行使用逗号运算符。 For code like a, b it first evaluates a , discards the result and then evaluates b and keeps that result as result of the overall expression. 对于像a, b这样的代码a, b它首先求a ,舍弃结果,然后求b并将该结果保留为整个表达式的结果。 That's not what you intended. 那不是你想要的。

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

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