Использование ostream с перегрузкой арифметических операторов для класса - PullRequest
0 голосов
/ 03 ноября 2018

У меня есть класс Rational, его фрагмент:

class Rational {
private:
    int numerator;
    int denominator;
    void saveAsIrreducible();
    gcd(int x, inty);
public: 
    Rational(int numerator, int denominator=1);
    Rational operator*(Rational &r);
    friend ostream& operator<<(ostream &output, Rational &r);
}

И реализация:

Rational::Rational(int numerator, int denominator) {
    this->numerator = numerator;
    this->denominator = denominator;
    this->saveAsIrreducible();
}

Rational Rational::operator*(Rational &r) {
    Rational r2 = Rational((this->numerator*r.numerator), (this->denominator*r.denominator));
    return r2;
}

ostream& operator<<(ostream &output, Rational &r) {
    output << r.numerator;

    if(r.denominator!=1)
        output << "|" << r.denominator;

    return output;
}

void Rational::saveAsIrreducible() {
    int greatestCommonDivisor = gcd(numerator, denominator);
    numerator = numerator/greatestCommonDivisor;
    denominator = denominator/greatestCommonDivisor;
    if(numerator > 0 && denominator < 0) { /* for example for 3|-2, after arithmetic operations */
        numerator = -numerator;
        denominator = -denominator;
    }
}

int Rational::gcd(int x, int y) {
    while(y!=0) {
        int r = x%y;
        x = y;
        y = r;
    }

    return x;
}

У меня проблема с использованием оператора * с cout. Например, это работает:

Rational r1(3,5), r2(3,6);
Rational r3 = r1*r2;
cout << r3 << endl;

Вывод правильный. Но когда я пытаюсь сделать это:

Rational r1(3,5), r2(3,6);
cout << r1*r2 << endl;

Я получаю много ошибок от компилятора:

Rational.cpp|186|error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'Rational')|

Rational.cpp|186|error: invalid initialization of non-const reference of type 'Rational&' from an rvalue of type 'Rational'|

Как решить эту проблему?

1 Ответ

0 голосов
/ 03 ноября 2018

Перегруженный operator<< принимает Rational& в качестве аргумента.

Так что в случае следующих утверждений:

Rational r3 = r1*r2;
cout << r3 << endl;

r3 - это lvalue (который содержит результат r1*r2), чья ссылка передается на operator<< и она успешно выполняется.

Но когда вы сделаете следующее:

cout << r1*r2 << endl;

Вы не передаете ссылку на operator<<, потому что operator* возвращает временное значение. Так что не получается.

Чтобы решить эту проблему, вы можете использовать const Rational & в качестве параметра operator<<. Вам придется изменить и объявление, и определение operator<<.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...