khaleesi0712
khaleesi0712

Reputation: 31

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;

Upvotes: 0

Views: 316

Answers (1)

RoQuOTriX
RoQuOTriX

Reputation: 3001

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;

Upvotes: 2

Related Questions