これらのような質問はたくさんありますが、私に合った解決策は見つかりませんでした。
私は、任意の数の関数を加算または減算し、答えを簡約分数として書き込むことができる単純な分数計算機を作成しようとしています。
例:input = 3/2 + 4/8、output = 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
***私が抱えている問題は、プログラムを実行するときに過負荷操作エラーが発生することです:* error:overloaded 'operator <<' is must be binary operator(has 3 parameters)****
/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;
}
演算子はメンバー関数であり、メンバー関数は暗黙の最初のパラメーターを取ることを知っています。つまり、演算子は3つのパラメーターを取り、非メンバー関数であることが修正されます。ただし、このプログラムでは機能しません。私の場合、プログラムが機能するようにどのくらい正確に修正しますか?
どうもありがとうございました!
問題は、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;
}