Перегрузка оператора C ++ не работает должным образом - PullRequest
0 голосов
/ 03 марта 2019

Вот весь класс (копирование / вставка должно работать):

#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;
}

Я хочу использовать перегрузку оператора, не являющегося членом.Код компилируется, но отображает неверные результаты.Последние две строки должны отображать:

7 + 5/3 = 26/3

14 + 5/3 = 47/3

, но вместо этого отображается:

7 + 5/3 = 3

14 + 5/3 = 3

Скорее всего, проблема заключается в следующем:

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

, потому что он работает правильно, если я сначала изменяю его для создания объекта, а затем возвращаю:

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

Я ожидал бы неявного преобразования иоба решения дают одинаковые результаты.Может ли кто-нибудь объяснить мне, в чем здесь разница?

Ответы [ 2 ]

0 голосов
/ 03 марта 2019

Эта строка вызывает вашу ошибку:

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

Проблема в том, что она оценивается как целое, что дает вам целое число.Это целое число затем передается неявно вызванному конструктору вашего класса Rational.Обратите внимание, что в этой строке используется запятая.Для кода, подобного a, b, он сначала оценивает a, отбрасывает результат, а затем оценивает b и сохраняет этот результат как результат общего выражения.Это не то, что вы намеревались.

0 голосов
/ 03 марта 2019

return оператор содержит вызов оператора запятой, отбрасывающий результат первого выражения (который должен был быть числителем) и вызов конструктора только с одним параметром.Вы должны использовать правильный синтаксис инициализации:

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

или

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

или (лучше)

return Rational
{
    (lhs.numerator() * rhs.denominator()) + (lhs.denominator() * rhs.numerator())
,   lhs.denominator() * rhs.denominator()
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...