Ошибка: перегруженный "оператор <<" должен быть двоичным оператором (имеет 3 параметра)

Я знаю, что таких вопросов много, но я не смог найти решение, которое бы сработало для меня.

Я пытаюсь сделать простой калькулятор дробей, который может добавить или вычесть любое количество функций и написать ответ как сокращенную дробь.

Пример: вход = 3/2 + 4/8, выход = 2

Я пытаюсь перегрузить операторы для достижения этой цели.

Таким образом, в программе, которую я пытаюсь разработать, ввод состоит из выражения, состоящего из дробей, разделенных операторами + или -.

Количество дробей в выражении произвольно.

Каждая из следующих 6 строк является примером допустимого входного выражения:

1/2 + 3/4
1/2 -5/7+3/5
355/113
3    /9-21/    -7
4/7-5/-8
-2/-3+7/5

*** Проблема, с которой я сталкиваюсь, заключается в том, что при запуске моей программы возникает ошибка при перегрузке: * ошибка: перегруженный оператор '<< должен быть двоичным оператором (имеет 3 параметра) ****

  /Users/Spicycurryman/Desktop/ECS40/hw1/fraction.cpp:61:22: error: overloaded 'operator<<' must be a binary operator (has 3 parameters)
  ostream& Fraction::operator<<(ostream &os, Fraction& n)
                     ^
/Users/Spicycurryman/Desktop/ECS40/hw1/fraction.cpp:80:22: error: overloaded 'operator>>' must be a binary operator (has 3 parameters)
  istream& Fraction::operator>>(istream &os, Fraction& n)

Я не понимаю, почему это ошибка.

Мой следующий код ниже:

CPP FILE

#include "Fraction.h"

Fraction::Fraction(int a, int b)
{

}
int Fraction::find_gcd (int n1, int n2) 
{
  int gcd, remainder;

  remainder = n1 % n2; 
  while ( remainder != 0 )
  {
    n1 = n2;
    n2 = remainder; 
    remainder = n1 % n2; 
  } 
  gcd = n2; 

  return (gcd);
}

void Fraction::reduce_fraction(int nump,  int denomp) 
{
  this->nump = nump;
  this->denomp = denomp; 
  int gcd;   
  gcd = find_gcd(nump, denomp);
  nump = nump / gcd;
  denomp = denomp / gcd;

    if ((denomp<0 && nump < 0 ))
    {
        denomp*=-1;
        nump*=-1;
    }
    else if (denomp < 0 &&  nump >0){
        denomp*=-1;

    }
    if ( denomp ==0) {
        throw invalid_argument( "Error: zero denominator" );
    }   
}



Fraction& Fraction::operator+(const Fraction& n) {
    denom = denomp * n.denom;
    numera = (nump * n.numera) + (n.denom * n.nump);
    return (*this);

}

Fraction& Fraction::operator-(const Fraction& n) {
    denom = denomp * n.denom;
    numera = (nump * n.numera) - (n.denom* n.nump);
    return (*this);
}

  ostream& Fraction::operator<<(ostream &os, Fraction& n)
{
    if (n.numera == 0)
    {
        cout << 0 << endl;
        return os;
    }
    else if (n.numera == n.denom)
    {
        cout << 1 << endl;
        return os;
    }
    else
    {
        cout << n.numera << '/' << n.denom << endl;
        return os;
    }
}

  istream& Fraction::operator>>(istream &os, Fraction& n)
{
    char slash = 0;
    return os >> n.numera >> slash >> n.denom;

}

Заголовочный файл

#ifndef FRACTION_H
#define FRACTION_H
#include <iostream>
#include <stdexcept>
using namespace std;


class Fraction{

    public: 
    Fraction(int a, int b);
    int fraction(int a,int b);
    int find_gcd(int n1, int n2); 
    void reduce_fraction(int nump,  int denomp);
    Fraction& operator+(const Fraction& n);
    Fraction& operator-(const Fraction& n);
    friend ostream& operator<<(ostream &os, const  Fraction& n);
    friend istream& operator>>(istream &is, const Fraction& n);
private:
    int denom;
    int numera;
    int denomp;
    int nump;



};

#endif

ОСНОВНОЙ ФАЙЛ CPP

#include "Fraction.h"
#include <iostream>
using namespace std;

int main()
{
  Fraction x(2,3);
  Fraction y(6,-2);

  cout << x << endl;
  cout << y << endl;

  cin >> y;
  cout << y << endl;
  Fraction z = x + y;
  cout << x << " + " << y << " = " << z << endl;
}

Я знаю, что операторы являются функциями-членами, и функция-член принимает неявный первый параметр, что означает, что мои операторы теперь принимают три параметра, которые могут быть исправлены как функция, не являющаяся членом; однако, это не будет работать в этой программе. Как именно в моем случае я это исправлю, чтобы программа работала?

Большое спасибо!

Ответы

Ответ 1

Проблема заключается в том, что вы объявили operator>> и operator<< как функции, отличные от членов, но определенные как члены.

Это должно устранить эту проблему (но открыть другой набор проблем). Поэтому вместо

  ostream& Fraction::operator<<(ostream &os, Fraction& n)
  {
     ...


  istream& Fraction::operator>>(istream &os, Fraction& n)
  {
     ...

реализовать как:

  ostream& operator<<(ostream &os, Fraction& n)
{
...

  istream& operator>>(istream &os, Fraction& n)
{
...

Кроме того, обратите внимание, что вы объявили функции как:

friend ostream& operator<<(ostream &os, const  Fraction& n);
friend istream& operator>>(istream &is, const Fraction& n);

но определяется как (поэтому вы изменили подпись):

  ostream& Fraction::operator<<(ostream &os, Fraction& n)
  istream& Fraction::operator>>(istream &os, Fraction& n)

Правильный способ - объявить и определить как:

  ostream& Fraction::operator<<(ostream &os, const Fraction& n)
  istream& Fraction::operator>>(istream &os, Fraction& n)

Я добавляю только изменения. Остальное - то же, что и в вопросе:

class Fraction{
    friend ostream& operator<<(ostream &os, const  Fraction& n);
    friend istream& operator>>(istream &is, Fraction& n);
  // the rest is the same
};

ostream& operator<<(ostream &os, const Fraction& n)
{
    if (n.numera == 0)
    {
        cout << 0 << endl;
        return os;
    }
    else if (n.numera == n.denom)
    {
        cout << 1 << endl;
        return os;
    }
    else
    {
        cout << n.numera << '/' << n.denom << endl;
        return os;
    }
}

  istream&  operator>>(istream &os, Fraction& n)
{
    char slash = 0;
    return os >> n.numera >> slash >> n.denom;

}