错误:重载的 'operator<<' 必须是二元运算符(有 3 个参数)

Posted

技术标签:

【中文标题】错误:重载的 \'operator<<\' 必须是二元运算符(有 3 个参数)【英文标题】:error: overloaded 'operator<<' must be a binary operator (has 3 parameters)错误:重载的 'operator<<' 必须是二元运算符(有 3 个参数) 【发布时间】:2014-06-13 15:39:34 【问题描述】:

我知道有很多这样的问题,但我找不到适合我的解决方案。

我正在尝试制作简单的分数计算器,它可以添加或减去任意数量的函数并将答案写为缩减分数。

示例:输入= 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

***我遇到的问题是,当我运行我的程序时,它有一个重载操作错误:*错误:重载的'operator

  /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 文件

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

我知道运算符是成员函数,成员函数采用隐式的第一个参数,这意味着我的运算符现在采用三个参数,它可能被固定为非成员函数;但是,这在该程序中不起作用。在我的情况下,我将如何修复它以使程序正常工作?

非常感谢!

【问题讨论】:

你可以使用朋友非会员功能。 好友函数不是成员函数。成员函数不需要成为朋友,因为它们已经拥有私有访问权限。 在您的operator&lt;&lt;( ostream&amp; os, ... ) 中,您应该输出到os 而不是cout 问题只与 How to properly overload the << operator for an ostream? 的可能重复项 【参考方案1】:

问题是您将operator&gt;&gt;operator&lt;&lt; 声明为非成员函数,但定义为成员函数。

这应该可以解决该问题(但会引发另一组问题)。所以不是

  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;


【讨论】:

当我完全使用 makefile 运行程序时,因为它们不同 这取决于你在哪里定义了操作符>>,如果你在头部实现操作符,它必须被声明为内联。在 Fraction.h 中内联 istream& 运算符>>(istream &os, Fraction& n) 如果在 Fraction.h 中声明函数但在 Fraction.cpp 中实现它,则不需要将其设为内联函数。这可能取决于编译器。 @BЈовић,你提到的另一组问题是什么?

以上是关于错误:重载的 'operator<<' 必须是二元运算符(有 3 个参数)的主要内容,如果未能解决你的问题,请参考以下文章

即使我重载了`operator<<`,也不能在类中使用`cout`

使用operator ==进行结构重载

为啥在c++中实现基于类的优先级队列时需要重载operator<?

重载operator new delete函数

为什么operator<<;;运算符重载一定要为友元函数呢?

重载operator<<运算符时第二个参数最好不能写成指向对象的指针