Redefinition of class in CPP File Error - c++

I know there are plenty of questions like these, but I couldn't find a solution that worked for me.
Okay, I am trying to make simple fraction calculator than can add or subtract any number of functions and write the answer as a reduced fraction.
Example: input=
3/2 + 4/
8
, output =
2
I am trying overload operators in order to accomplish this.
So in the program, I am trying to develop the input consists of an expression made of fractions separated by the operators '+'or '-'.
The number of fractions in the expression is arbitrary.
Each of the following 6 lines is an example of valid input expression:
1/2 + 3/4
1/2 -5/7+3/5
355/113
3 /9-21/ -7
4/7-5/-8
-2/-3+7/5
The problem that I am having is that in when I run my Main CPP program it has a class redefinition error:
fraction.cpp:6:7: error: redefinition of 'Fraction'
class Fraction
^
./Fraction.h:7:7: note: previous definition is here
class Fraction{
However, that should not be a problem because I declared the class and member functions in my header files and defined them in my CPP file.
My following code is below:
Header File
#ifndef FRACTION_H
#define FRACTION_H
#include <iostream>
using namespace std;
class Fraction{
public:
Fraction(int , int );
int fraction(int,int);
void reduce_fraction(int *, int *);
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);
};
#endif
CPP File
#include <iostream>
using namespace std;
#include "Fraction.h"
#include <stdexcept>
class Fraction
{
public:
Fraction::Fraction(int a, int b);
int find_gcd(int n1, int n2);
void reduce_fraction(int *nump, int *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) {
int denom = *denomp * n.denom;
int numera = (*nump * n.numera) + (n.denom * n.nump);
return Fraction(numera,denom);
}
Fraction& Fraction::operator-(const Fraction& n) {
int denom = *denomp * n.denom;
int numera = (*nump * n.numera) - (n.denom* n.nump);
return Fraction(numera, denom);
}
friend ostream& 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;
}
}
friend istream& operator>>(istream &os, Fraction& n)
{
char slash = 0;
return is >> n.numera >> slash >> n.denom;
}
};
#include <iostream>
using namespace std;
#include "Fraction.h"
#include <stdexcept>
class Fraction
{
public:
Fraction::Fraction(int a, int b);
int find_gcd(int n1, int n2);
void reduce_fraction(int *nump, int *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) {
int denom = *denomp * n.denom;
int numera = (*nump * n.numera) + (n.denom * n.nump);
return Fraction(numera,denom);
}
Fraction& Fraction::operator-(const Fraction& n) {
int denom = *denomp * n.denom;
int numera = (*nump * n.numera) - (n.denom* n.nump);
return Fraction(numera, denom);
}
friend ostream& 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;
}
}
friend istream& operator>>(istream &os, Fraction& n)
{
char slash = 0;
return is >> n.numera >> slash >> n.denom;
}
};
MAIN CPP FILE
#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;
}
I am essentially having trouble with understanding why I am getting the previous definition error and how exactly to fix it. Also, if you see anything else wrong with my implementation in this program I would appreciate you telling me!
Thank you very much!

The way to define member functions in Fraction.cpp is not like this:
class Fraction
{
public:
void reduce_fraction(int *nump, int *denomp)
{
...
}
}
but rather like this:
void Fraction::reduce_fraction(int *nump, int *denomp)
{
...
}
More generally, you should not write this much code before testing any of it.

Related

Writing a fraction class and I cannot figure out these errors

I'm writing a fraction.cpp and fraction.h that inputs fraction types and does mathematical operations on them. I have a weird error that says "undefined reference", but the reference is defined as far as I can see. There's also a bunch of errors that say "no matching function for call to fraction::outputFormat(fracForm)" and "candidate is" and others. Here is all of my code for reference:
main.cpp
#include <iostream>
#include <iomanip>
using namespace std;
#include "fraction.h"
int main()
{
fraction f0;
fraction f1;
cin >> f0; // input format numerator/denominator, ex 23/9
cout << "input: " << f0 << endl; // outputs what was input
// Note the << and >> operators should also work for file streams
// cin >> f0 >> f1; // reads 2 fractions, ex 8/5 12/16
f1.setFraction(17,6); // 17/6
cout << f1.getNumerator() << '/' << f1.getDenominator() << endl; // 17/6
f1.setFraction(-4.75); // -19/4
cout << f1.decimalValue() << endl; // outputs -4.75
fraction f2(4,8); // 4/8
fraction f3(2.875); // 2 7/8
cout << f3 << endl; // outputs 2 7/8 (the default output format is mixed)
cout << f2 << endl; // outputs 4/8
fraction f4(16,8);
cout << f4 << endl; // outputs 2
fraction::outputFormat(improper); // set output format to improper fraction
cout << f4 << endl; // outputs 16/8
cout << f3 << endl; // outputs 23/8
cout << f1 << endl; // outputs -19/4
fraction::outputFormat(decimal); // set output format to decimal value
cout << f3 << endl; // outputs 2.875
cout << f2 << endl; // outputs 0.5
cout << f1 << endl; // outputs -4.75
fraction::outputFormat(mixed); // set output format back to default mixed
cout << f3 << endl; // outputs 2 7/8
f1.setFraction(-4.75);
cout << f1 << endl; // outputs -4 3/4
cout << f2 << endl; // outputs 4/8
fraction f5(12,8);
fraction::outputFormat(improper);
cout << f5 << endl; // outputs 12/8
f2.reduce(); // convert to lowest terms
f5.reduce();
cout << f2 << endl; // outputs 1/2
cout << f5 << endl; // outputs 3/2
f5.setDenominator(16); // change denominator and numerator
// error if numerator is not a whole number
cout << f5 << endl; // outputs 24/16
f5.setDenominator(22);
cout << f5 << endl; // outputs 33/22
f5.setDenominator(5); // output error as numerator would have to be 7.5
cout << f5 << endl; // outputs 33/22 (fraction remained the same)
f1 = f3+f2; // f1 put in lowest terms
cout << f1 << endl; // outputs 27/8
f1 = f3-f2;
cout << f1 << endl;
f1 = f3*f2;
cout << f1 << endl;
f1 = f3/f2;
cout << f1 << endl;
f1 = f3;
cout << f1 << endl; // outputs 23/8
f1 = 7.75;
f1 = f2 = 7.75;
cout << f1 << endl; // outputs 31/4
cout << setw(6) << f1 << setw(6) << f2 << endl; // outputs 31/4 31/4
f0.setFraction(31,4);
if (f0 == f1)
cout << "correct\n";
else
cout << "incorrect\n";
// all relational operators should work for comparing 2 fractions
if (f0 == 7.75)
cout << "correct\n";
else
cout << "incorrect\n";
// all relational operators should work for comparing fraction to double
f0.setFraction(2);
if (f0 < 3)
cout << "correct\n";
else
cout << "incorrect\n";
// all relational operators should work for comparing fraction to int
return 0;
}
fraction.h
#ifndef fraction
#include <iostream>
using namespace std;
enum fracForm {improper, mixed, decimal};
class fraction {
enum fracForm {improper, mixed, decimal};
friend istream& operator>>(istream&, fraction&);
friend ostream& operator<<(ostream&, fraction&);
public:
fraction();
fraction(int, int);
fraction(double);
void setFraction(int, int);
void setFraction(double);
void setDenominator(int);
int getNumerator() const;
int getDenominator() const;
double decimalValue() const;
static void outputFormat(fracForm);
void reduce();
fraction operator+(const fraction&) const;
fraction operator-(const fraction&) const;
fraction operator*(const fraction&) const;
fraction operator/(const fraction&) const;
bool operator==(const fraction&) const;
bool operator!=(const fraction&) const;
bool operator<(const fraction&) const;
bool operator>(const fraction&) const;
bool operator<=(const fraction&) const;
bool operator>=(const fraction&) const;
fraction operator+(const int) const;
fraction operator-(const int) const;
fraction operator*(const int) const;
fraction operator/(const int) const;
bool operator==(const int) const;
bool operator!=(const int) const;
bool operator<(const int) const;
bool operator>(const int) const;
bool operator<=(const int) const;
bool operator>=(const int) const;
fraction operator+(const float) const;
fraction operator-(const float) const;
fraction operator*(const float) const;
fraction operator/(const float) const;
bool operator==(const float) const;
bool operator!=(const float) const;
bool operator<(const float) const;
bool operator>(const float) const;
bool operator<=(const float) const;
bool operator>=(const float) const;
fraction operator+(const double) const;
fraction operator-(const double) const;
fraction operator*(const double) const;
fraction operator/(const double) const;
bool operator==(const double) const;
bool operator!=(const double) const;
bool operator<(const double) const;
bool operator>(const double) const;
bool operator<=(const double) const;
bool operator>=(const double) const;
string mix();
private:
int num, denom;
static fracForm format;
};
#endif
fraction.cpp
#include "fraction.h"
#include <iostream>
#include <algorithm>
fraction::fraction() {
num = 0;
denom = 1;
}
fraction::fraction(int numerator, int denominator) {
setFraction(numerator, denominator);
}
fraction::fraction(double deci) {
setFraction(deci);
}
void fraction::setFraction(int numerator, int denominator){
num = numerator;
denom = denominator;
}
void fraction::setFraction(double deci) {
int decimal = deci;
denom = 1;
while (deci != decimal) {
deci = deci * 10;
denom = denom * 10;
decimal = deci;
}
num = deci;
reduce();
}
void fraction::setDenominator(int denominator) {
int denom2 = denominator;
int proportion = num * denom2;
double newProp = proportion / denom;
int intProp = newProp;
if (newProp != intProp) {
try
{
throw 20;
}
catch (int n)
{
cout << "This does not create a fraction with integers." << endl;
}
}
else {num = newProp; denom = denom2;}
}
int fraction::getNumerator() const {
return num;
}
int fraction::getDenominator() const{
return denom;
}
double fraction::decimalValue() const {
double deci = num/denom;
return deci;
}
void fraction::outputFormat(fracForm fType) {
format = fType;
}
void fraction::reduce() {
num = num / __gcd(num, denom);
denom = denom / __gcd(num, denom);
}
fraction fraction::operator+(const fraction& frac) const {
return fraction(decimalValue() + frac.decimalValue());
}
fraction fraction::operator-(const fraction& frac) const {
return fraction(decimalValue() - frac.decimalValue());
}
fraction fraction::operator*(const fraction& frac) const {
return fraction(decimalValue() * frac.decimalValue());
}
fraction fraction::operator/(const fraction& frac) const {
return fraction(decimalValue() / frac.decimalValue());
}
bool fraction::operator==(const fraction& frac) const {
return decimalValue() == frac.decimalValue();
}
bool fraction::operator!=(const fraction& frac) const {
return decimalValue() != frac.decimalValue();
}
bool fraction::operator<(const fraction& frac) const {
return decimalValue() < frac.decimalValue();
}
bool fraction::operator>(const fraction& frac) const {
return decimalValue() > frac.decimalValue();
}
bool fraction::operator<=(const fraction& frac) const {
return decimalValue() <= frac.decimalValue();
}
bool fraction::operator>=(const fraction& frac) const {
return decimalValue() >= frac.decimalValue();
}
fraction fraction::operator+(const int frac) const {
return fraction(decimalValue() + frac);
}
fraction fraction::operator-(const int frac) const {
return fraction(decimalValue() - frac);
}
fraction fraction::operator*(const int frac) const {
return fraction(decimalValue() * frac);
}
fraction fraction::operator/(const int frac) const {
return fraction(decimalValue() / frac);
}
bool fraction::operator==(const int frac) const {
return decimalValue() == frac;
}
bool fraction::operator!=(const int frac) const {
return decimalValue() != frac;
}
bool fraction::operator<(const int frac) const {
return decimalValue() < frac;
}
bool fraction::operator>(const int frac) const {
return decimalValue() > frac;
}
bool fraction::operator<=(const int frac) const {
return decimalValue() <= frac;
}
bool fraction::operator>=(const int frac) const {
return decimalValue() >= frac;
}
fraction fraction::operator+(const float frac) const {
return fraction(decimalValue() + frac);
}
fraction fraction::operator-(const float frac) const {
return fraction(decimalValue() - frac);
}
fraction fraction::operator*(const float frac) const {
return fraction(decimalValue() * frac);
}
fraction fraction::operator/(const float frac) const {
return fraction(decimalValue() / frac);
}
bool fraction::operator==(const float frac) const {
return decimalValue() == frac;
}
bool fraction::operator!=(const float frac) const {
return decimalValue() != frac;
}
bool fraction::operator<(const float frac) const {
return decimalValue() < frac;
}
bool fraction::operator>(const float frac) const {
return decimalValue() > frac;
}
bool fraction::operator<=(const float frac) const {
return decimalValue() <= frac;
}
bool fraction::operator>=(const float frac) const {
return decimalValue() >= frac;
}
fraction fraction::operator+(const double frac) const {
return fraction(decimalValue() + frac);
}
fraction fraction::operator-(const double frac) const {
return fraction(decimalValue() - frac);
}
fraction fraction::operator*(const double frac) const {
return fraction(decimalValue() * frac);
}
fraction fraction::operator/(const double frac) const {
return fraction(decimalValue() / frac);
}
bool fraction::operator==(const double frac) const {
return decimalValue() == frac;
}
bool fraction::operator!=(const double frac) const {
return decimalValue() != frac;
}
bool fraction::operator<(const double frac) const {
return decimalValue() < frac;
}
bool fraction::operator>(const double frac) const {
return decimalValue() > frac;
}
bool fraction::operator<=(const double frac) const {
return decimalValue() <= frac;
}
bool fraction::operator>=(const double frac) const {
return decimalValue() >= frac;
}
fraction::mix() {
int integer = 0;
int n = num;
while (num > denom) {
num = num - denom;
integer = integer + 1;
}
return to_string(integer) + " " + to_string(num) + "/" + to_string(denom);
}
istream& operator>>(istream& in, fraction& frac) {
in >> frac.num;
char i;
in >> i;
in >> frac.denom;
return i;
}
ostream& operator<<(ostream& out, fraction& frac) {
switch (frac.format) {
case improper:
out << to_string(frac.getNumerator()) + "/" + to_string(frac.getDenominator()); break;
case decimal:
out << frac.decimalValue(); break;
case mixed:
out << frac.mix(); break;
}
}
Here are the specific errors:
main.cpp: In function ‘int main()’:
main.cpp:27:35: error: no matching function for call to ‘fraction::outputFormat(fracForm)’
fraction::outputFormat(improper); // set output format to improper fraction
^
In file included from main.cpp:4:0:
fraction.h:27:21: note: candidate: static void fraction::outputFormat(fraction::fracForm)
static void outputFormat(fracForm);
^~~~~~~~~~~~
fraction.h:27:21: note: no known conversion for argument 1 from ‘fracForm’ to ‘fraction::fracForm’
main.cpp:32:34: error: no matching function for call to ‘fraction::outputFormat(fracForm)’
fraction::outputFormat(decimal); // set output format to decimal value
^
In file included from main.cpp:4:0:
fraction.h:27:21: note: candidate: static void fraction::outputFormat(fraction::fracForm)
static void outputFormat(fracForm);
^~~~~~~~~~~~
fraction.h:27:21: note: no known conversion for argument 1 from ‘fracForm’ to ‘fraction::fracForm’
main.cpp:37:32: error: no matching function for call to ‘fraction::outputFormat(fracForm)’
fraction::outputFormat(mixed); // set output format back to default mixed
^
In file included from main.cpp:4:0:
fraction.h:27:21: note: candidate: static void fraction::outputFormat(fraction::fracForm)
static void outputFormat(fracForm);
^~~~~~~~~~~~
fraction.h:27:21: note: no known conversion for argument 1 from ‘fracForm’ to ‘fraction::fracForm’
main.cpp:44:35: error: no matching function for call to ‘fraction::outputFormat(fracForm)’
fraction::outputFormat(improper);
^
In file included from main.cpp:4:0:
fraction.h:27:21: note: candidate: static void fraction::outputFormat(fraction::fracForm)
static void outputFormat(fracForm);
^~~~~~~~~~~~
fraction.h:27:21: note: no known conversion for argument 1 from ‘fracForm’ to ‘fraction::fracForm’
fraction.cpp:235:15: error: ISO C++ forbids declaration of ‘mix’ with no type [-fpermissive]
fraction::mix() {
^
fraction.cpp:235:1: error: prototype for ‘int fraction::mix()’ does not match any in class ‘fraction’
fraction::mix() {
^~~~~~~~
In file included from fraction.cpp:1:0:
fraction.h:69:16: error: candidate is: std::string fraction::mix()
string mix();
^~~
fraction.cpp: In function ‘std::istream& operator>>(std::istream&, fraction&)’:
fraction.cpp:250:12: error: invalid initialization of reference of type ‘std::istream& {aka std::basic_istream&}’ from expression of type ‘char’
return i;
You declare the enum fracForm two times:
enum fracForm {improper, mixed, decimal};
class fraction {
enum fracForm {improper, mixed, decimal};
The functions in class fraction are now using the enum fraction::fracForm, and the code outside (so in main.cpp) uses fracForm
These two enums aren't the same, so the code won't compile.
To solve the problem, you can use either the "global" approach, where fracForm is resolved from the fraction class:
enum fracForm {improper, mixed, decimal};
class fraction {
//enum fracForm {improper, mixed, decimal};
With that solution, I would think most errors are gone.
The other solution would be, to put the fracForm error in the fraction class scope:
//enum fracForm {improper, mixed, decimal};
class fraction {
public:
enum fracForm {improper, mixed, decimal};
Now you have to use the enum outside the class like:
fracForm type = fraction::improper;

How to define some function which can be accessed from within the scope of operator overloading for (+) operator?

I created a code by using operator overloading concept in c++ for addition of two rational numbers by overloading the +(plus) and the <<(Insertion) operator and I am not able to get a function being accessed from the scope of operator overloading of + operator. How to access the LCM() function from the scope of operator+ overloaded?
I tried using the friend function to access my LCM() function from within the scope of operator+ overloaded function but it didn't work!
#include <iostream>
using namespace std;
class Rational {
private:
int num, den;
public:
int getnum()
{
return this->num;
}
int getden()
{
return this->den;
}
Rational(int num = 0, int den = 0)
{
this->num = num;
this->den = den;
}
int LCM(int a, int b);
friend ostream& operator<<(ostream& out, Rational& r);
friend Rational operator+(Rational x, Rational y);
};
int Rational::LCM(int a, int b)
{
int i = a > b ? a : b;
for (i; i <= a * b; i++) {
if (i % a == 0 && i % b == 0) {
break;
}
}
return i;
}
ostream& operator<<(ostream& out, Rational& r)
{
out << r.getnum() << "/" << r.getden();
return out;
}
Rational operator+(Rational x, Rational y)
{
Rational temp;
int temp1;
int div;
temp1 = LCM(x.den, y.den);
temp.num = (int(temp1 / x.den) * x.num) + (int(temp1 / y.den) * y.num);
temp.den = temp1;
return temp;
}
int main()
{
Rational r1(3, 2);
Rational r2(9, 4);
Rational r3;
r3 = r1 + r2;
cout << r3;
return 0;
}
And I get the error:
error: ‘LCM’ was not declared in this scope
I would say that int Rational::LCM(int a,int b) does not really have anything to do with the Rational class and should probably be a utility function (non-member function), then you would be able to use it anywhere

C++: Errors while compilation of C++ program

I am making a class Fraction with global functions usage
My code looks like below:
#include<iostream>
using namespace std;
ostream & operator<<(ostream & os, Fraction & fr)
{
return os << fr.get_num() << '/' << fr.get_den();
}
class Fraction
{
private:
int num, den;
public:
int get_num()
{
return num;
}
int get_den()
{
return den;
}
};
Main function has call : `cout << f2 << endl;
But i am getting following build erros while compilation:
Error C2805 binary 'operator <<' has too few parameters
fr: undeclared identifier
left of get_num must be struct/union/class
You should change the order of your code like this:
class Fraction
{
private:
int num, den;
public:
int get_num()
{
return num;
}
int get_den()
{
return den;
}
};
ostream & operator<<(ostream & os, Fraction & fr)
{
return os << fr.get_num() << '/' << fr.get_den();
}

It says "No matching constructor for initialization of 'Fraction'

.cpp
//
// calculator.cpp
//
#include "Fraction.h"
#include<iostream>
#include<stdexcept>
using namespace std;
int main()
{
Fraction x,y; //ERROR IS RIGHT HERE. It says "No matching constructor for initialization of 'Fraction'
char op;
try
{
cin >> x;
cin >> op;
while ( cin && ( op == '+' || op == '-' ) )
{
cin >> y;
if ( op == '+' )
x = x + y;
else
x = x - y;
cin >> op;
}
cout << x << endl;
}
catch ( invalid_argument& e )
{
cout << "Error: " << e.what() << endl;
}
}
.h
#ifndef Fraction_Calculator_Fraction_h
#define Fraction_Calculator_Fraction_h
#include<iostream>
#include<cstdlib>
//Fraction class definition
class Fraction
{
public:
Fraction (int a, int b);
int fraction(int a, int b);
void set(int, int);
int get_numerator(void);
int get_denomenator(void);
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 std::ostream& operator<<(std::ostream &os, const Fraction& n);
friend std::istream& operator>>(std::istream &is, Fraction& n);
Fraction& operator= (const Fraction& n);
int denom;
int numera;
private:
int numerator;
int denomenator;
int denomp;
int nump;
};
#endif
It says "No matching constructor for initialization of 'Fraction' on the first line of the cpp file
I don't understand what it means.
The problem is that your Fraction constructor takes 2 arguments.
Fraction (int a, int b);
and you are invoking it with none
Fraction x,y; //ERROR IS RIGHT HERE. It says "No matching constructor for initialization of 'Fraction'
You should either invoke x and y with the 2 int parameters or define another constructor that takes no arguments.
Provide default constructor like
Fraction()
{
numerator=0;
denomenator0;
denomp0;
nump=0;
}

error: overloaded 'operator<<' must be a binary operator (has 3 parameters)

I know there are plenty of questions like these, but I couldn't find a solution that worked for me.
I am trying to make simple fraction calculator than can add or subtract any number of functions and write the answer as a reduced fraction.
Example: input=
3/2 + 4/
8
, output =
2
I am trying overload operators in order to accomplish this.
So in the program I am trying to develop, the input consists of an expression made of fractions separated by the operators + or -.
The number of fractions in the expression is arbitrary.
Each of the following 6 lines is an example of a valid input expression:
1/2 + 3/4
1/2 -5/7+3/5
355/113
3 /9-21/ -7
4/7-5/-8
-2/-3+7/5
***The problem that I am having is that in when I run my program it has an overload operating error: *error: overloaded 'operator<<' must be a 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)
I don't understand why that is an error.
My following code is below:
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;
}
Header File
#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
MAIN CPP FILE
#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;
}
I know that the operators are member functions and a member function takes an implicit first parameter, meaning my operators now takes three parameters it may be fixed being a non-member function; however, that would not work in this program. How exactly in my case would I fix it so the program would work?
Thank you very much!
The problem is that you declared operator>> and operator<< as non-member functions, but defined as a member function.
This should fix that problem (but open another set of problems). So instead of
ostream& Fraction::operator<<(ostream &os, Fraction& n)
{
...
istream& Fraction::operator>>(istream &os, Fraction& n)
{
...
implement as :
ostream& operator<<(ostream &os, Fraction& n)
{
...
istream& operator>>(istream &os, Fraction& n)
{
...
Also, take a note that you declared functions as :
friend ostream& operator<<(ostream &os, const Fraction& n);
friend istream& operator>>(istream &is, const Fraction& n);
but defined as (therefore you changed the signature) :
ostream& Fraction::operator<<(ostream &os, Fraction& n)
istream& Fraction::operator>>(istream &os, Fraction& n)
Proper way is to declare and define as :
ostream& Fraction::operator<<(ostream &os, const Fraction& n)
istream& Fraction::operator>>(istream &os, Fraction& n)
I am adding just changes. The rest is the same as in the question:
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;
}