Help with overloaded operators

I am so stuck. Any assistance will result in my undying gratitude. Unfortunately, I don't have much else to offer.

Here are the instructions for my assignment:

Imagine that the company you work for is going to create a lot of tutorials on Fractions. You are to create a robust Fraction class that will have all of the following (all examples are for a fraction half that has a numerator of 1 and a denominator of 2):

Private integers numerator and denominator ;

All public getter and setter functions for the numerator and denominator;

Safeguard that the denominator will NEVER become 0!

a default constructor with no arguments;

a constructor that accepts both the numerator and denominator;

a toDecimal method that returns the decimal value of the fraction, example: 1/2 will be 0.5;

a toString method that will return the fraction as a string, , example: 1/2 will be "1/2";

a reduce method that will change the numerator and denominator by finding a common denominator and reducing the fraction. Example 3/12 becomes 1/4;

Expand your Fraction class to include all of the following (all examples are for a fraction half that has a numerator of 1 and a denominator of 2):

Overload ==, <, <=, >, >= operators (use the decimal values to compare);

Overload = operator (assigns the numerator and denominator to the fraction);

Overload ++ so that 1/3 becomes 2/3 for example.

Overload -- so that 2/3 becomes 1/3 for eaxample.

It is OK if the numerator is negative.

Here's the code I have so far. Everything is working except for the overloaded -- and ++ operations. The functions work if I have the functions print out information. The information just isn't getting back to the main function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
  #include <iostream>
#include <cmath>
#include <sstream>
using namespace std;

class Fraction
{
private:
int numerator;
int denominator;
public:
Fraction(){};
Fraction(int num, int denom)
{
numerator = num;
if (denom==0)
   exit(0);
else if (denom!=0)
   denominator = denom;
}
  
void setNumerator(double num)
{
numerator=num;
}
  
void setDenominator(double denom)
{
if (denom==0)
   exit(0);
else if (denom != 0)
denominator=denom;

}
  
double toDecimal(double num, double denom)
{
return num/denom;
}
  
string toString(double number)
{
string String=static_cast<ostringstream*>(&(ostringstream() << number) )->str();
return String;
}
  
double reduce(double num, double denom)
{
if(denom==0)
return num;
  
else
return reduce(denom, fmod(num, denom));
}

  
void operator ++(int)
{
numerator++;
denominator++;
}
  
void operator --(int)
{
if(denominator-1 !=0)
{
denominator--;
numerator--;
}
}
  
void operator=(const Fraction &copyfrom)
{
numerator=copyfrom.numerator;
denominator=copyfrom.denominator;
}
  
bool operator > (const Fraction &right)
{
bool status;
if (numerator > right.numerator && denominator > right.denominator)
status=true;
else
status=false;
return status;
}
  
bool operator < (const Fraction &right)
{
bool status;
if (numerator<right.numerator && denominator < right.denominator)
status=true;
else
status=false;
return status;
}
  
bool operator == (const Fraction &right)
{
bool status;
if (numerator==right.numerator && denominator==right.denominator)
status=true;
else
status=false;
return status;
}
  
bool operator >= (const Fraction &right)
{
bool status;
if (numerator>right.numerator && denominator>right.denominator)
status=true;
else if (numerator==right.numerator && denominator==right.denominator)
status=true;
else
status=false;
return status;
}
  
bool operator <= (const Fraction &right)
{
bool status;
if (numerator<right.numerator && denominator<right.denominator)
status=true;
else if (numerator==right.numerator && denominator==right.denominator)
status=true;
else
status=false;
return status;
}
  
};

int main()
{
double num;
double denom;
double num2;
double denom2;
Fraction frac;
Fraction frac2;
Fraction frac3;
  
cout << "Please enter the numerator: ";
cin >> num;
frac.setNumerator(num);
  
cout << "Please enter the denominator: ";
cin >> denom;
frac.setDenominator(denom);
  
Fraction(num, denom);
  
cout << "Please enter the second numerator: ";
cin >> num2;
frac2.setNumerator(num2);
  
cout << "Please enter the second denominator: ";
cin >> denom2;
frac2.setDenominator(denom2);
  
Fraction(num2, denom2);

cout << "Your fraction is: " << num << "/" << denom << "." << endl;
cout << "As a decimal your fraction is: " << frac.toDecimal(num, denom) << "." << endl;
cout << "Your fraction as a string is: " << frac.toString(num) << "/" << frac.toString(denom) << "." << endl;
int gcd = frac.reduce(num, denom);
cout << "Your fraction reduced is: " << num/gcd << "/" << denom/gcd << "." << endl;
  
cout << "Your second fraction is: " << num2 << "/" << denom2 << "." << endl;
cout << "As a decimal your second fraction is: " << frac2.toDecimal(num2, denom2) << "." << endl;
cout << "Your second fraction as a string is: " << frac2.toString(num2) << "/" << frac2.toString(denom2) << "." << endl;
int gcd2=frac2.reduce(num2, denom2);
cout << "Your second fraction reduced is: "<< num2/gcd2 << "/" << denom2/gcd2 << "." << endl;
  
if (frac == frac2)
cout << "Your first fraction is equal to your second fraction." << endl;
if (frac > frac2)
cout << "Your first fraction is greater than your second fraction." << endl;
if (frac < frac2)
cout << "Your first fraction is less than your second fraction." << endl;
if (frac <= frac2)
cout << "Your first fraction is less than or equal to your second fraction." << endl;
if (frac >= frac2)
cout << "Your first fraction is greater than or equal to your second fraction." << endl;
cout << "I will now increment both fractions." << endl;
frac++;
frac2++;
cout << "Your first fraction: " << num << "/" << denom << endl;
cout << "Your second fraction: " << num2 << "/" << denom2 << endl;
  
  
  
return 0;
}


Thank you in advance for any help. I have spent a week beating my head against the well and getting no where.
Everything is working except for the overloaded -- and ++ operations.


Firstly you should be defining your class functions with the class scope operator ::
1
2
3
4
5
6
7
8
9
10
11
void Fraction::operator ++(int)
{
    numerator++;
    denominator++;
}

void Fraction::operator --(int)
{
    numerator++;
    denominator++;
}


Secondly you are returning a local variable numerator and not your fraction's numerator.
Same with your denominator.

So to actually print out your incremented fractions numerator/denominator use Getters.

1
2
3
4
5
6
7
8
9
int getNumerator()
{
    return numerator;
}

int getDenominator()
{
    return denominator;
}


So now you can print it like this:
1
2
cout << "Your first fraction: " << frac.getNumerator() << "/" << frac.getDenominator()<< endl;
cout << "Your second fraction: " << frac2.getNumerator() << "/" << frac2.getDenominator()<< endl;
There's a lot of areas where the code doesn't seem to go with the spirit of how a Fraction object might be expected to behave. An example, for printing you might do this:
 
    cout << "Your first fraction: " << frac.toString() << endl;


Another example is the reduce function which should not need to use any external help to do its work.
Instead of this,
1
2
    int gcd = frac.reduce(num, denom);
    cout << "Your fraction reduced is: " << num/gcd << "/" << denom/gcd << "." << endl;

it might be more like this:
1
2
    frac.reduce();
    cout << "Your fraction reduced is: " << frac.toString() << endl;

and so on.
Last edited on
Thank you everyone for your help!! I really appreciate it. I think I am closer but when it runs and has reduce two fractions it skips over comparing the fractions, like this;

Please enter the numerator: 6
Please enter the denominator: 8
Please enter the second numerator: 3
Please enter the second denominator: 12
Your fraction is: 6/8.
As a decimal your fraction is: 0.75.
Your fraction as a string is: 6/8.
Your fraction reduced is: 3/4.
Your second fraction is: 3/12.
As a decimal your second fraction is: 0.25.
Your second fraction as a string is: 3/12.
Your second fraction reduced is: 1/4.
I will now increment both fractions.
Your first fraction: 7/9
Your second fraction: 4/13
I will now decrement both fractions.
Your first fraction: 6/8
Your second fraction: 3/12

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#include <iostream>
#include <cmath>
#include <sstream>
using namespace std;

class Fraction
{
    private:
    int numerator;
    int denominator;
    public:
    Fraction(){};
    Fraction(int num, int denom)
    {
        numerator = num;
        if (denom==0)
          exit(0);
        else if (denom!=0)
          denominator = denom;
    }

  
void setNumerator(double num)
{
    numerator=num;
}
  
void setDenominator(double denom)
{
    if (denom==0)
       exit(0);
    else if (denom != 0)
        denominator=denom;

}
  
double toDecimal(double num, double denom)
{
    return num/denom;
}
  
string toString(double number)
{
    string String=static_cast<ostringstream*>(&(ostringstream() << number) )->str();
    return String;
}
  
double reduce(double num, double denom)
{
    if(denom==0)
    return num;
  
    else
    return reduce(denom, fmod(num, denom));
}

  
void operator ++(int)
{
    numerator++;
    denominator++;
}
  
void operator --(int)
{
    if(denominator-1 !=0)
    {
        denominator--;
        numerator--;
    }
}
  
void operator=(const Fraction &copyfrom)
{
    numerator=copyfrom.numerator;
    denominator=copyfrom.denominator;
}
  
bool operator > (const Fraction &right)
{
    bool status;
    if (numerator > right.numerator && denominator > right.denominator)
        status=true;
    else
        status=false;
    return status;
}
  
bool operator < (const Fraction &right)
{
    bool status;
    if (numerator<right.numerator && denominator < right.denominator)
        status=true;
    else
        status=false;
    return status;
}
  
bool operator == (const Fraction &right)
{
    bool status;
    if (numerator==right.numerator && denominator==right.denominator)
        status=true;
    else
        status=false;
    return status;
}
  
bool operator >= (const Fraction &right)
{
    bool status;
    if (numerator>right.numerator && denominator>right.denominator)
        status=true;
    else if (numerator==right.numerator && denominator==right.denominator)
        status=true;
    else
        status=false;
    return status;
}
  
bool operator <= (const Fraction &right)
{
    bool status;
    if (numerator<right.numerator && denominator<right.denominator)
        status=true;
    else if (numerator==right.numerator && denominator==right.denominator)
        status=true;
    else
        status=false;
    return status;
}
  
double getNumerator ()
{
    return numerator;
}

double getDenominator()
{
    return denominator;
}

};

int main()
{
double num;
double denom;
double num2;
double denom2;
Fraction frac;
Fraction frac2;
Fraction frac3;
  
cout << "Please enter the numerator: ";
cin >> num;
frac.setNumerator(num);
  
cout << "Please enter the denominator: ";
cin >> denom;
frac.setDenominator(denom);
  
Fraction(num, denom);
  
cout << "Please enter the second numerator: ";
cin >> num2;
frac2.setNumerator(num2);
  
cout << "Please enter the second denominator: ";
cin >> denom2;
frac2.setDenominator(denom2);
  
Fraction(num2, denom2);

cout << "Your fraction is: " << num << "/" << denom << "." << endl;
cout << "As a decimal your fraction is: " << frac.toDecimal(num, denom) << "." << endl;
cout << "Your fraction as a string is: " << frac.toString(num) << "/" << frac.toString(denom) << "." << endl;
int gcd = frac.reduce(num, denom);
cout << "Your fraction reduced is: " << num/gcd << "/" << denom/gcd << "." << endl;
  
cout << "Your second fraction is: " << num2 << "/" << denom2 << "." << endl;
cout << "As a decimal your second fraction is: " << frac2.toDecimal(num2, denom2) << "." << endl;
cout << "Your second fraction as a string is: " << frac2.toString(num2) << "/" << frac2.toString(denom2) << "." << endl;
int gcd2=frac2.reduce(num2, denom2);
cout << "Your second fraction reduced is: "<< num2/gcd2 << "/" << denom2/gcd2 << "." << endl;
  
if (frac == frac2)
{cout << "Your first fraction is equal to your second fraction." << endl;}
if (frac > frac2)
{cout << "Your first fraction is greater than your second fraction." << endl;}
if (frac < frac2)
{cout << "Your first fraction is less than your second fraction." << endl;}
if (frac <= frac2)
{cout << "Your first fraction is less than or equal to your second fraction." << endl;}
if (frac >= frac2)
{cout << "Your first fraction is greater than or equal to your second fraction." << endl;}
cout << "I will now increment both fractions." << endl;
frac++;
frac2++;
cout << "Your first fraction: " << frac.getNumerator() << "/" << frac.getDenominator() << endl;
cout << "Your second fraction: " << frac2.getNumerator() << "/" << frac2.getDenominator() << endl;
cout << "I will now decrement both fractions." << endl;
frac--;
frac2--;
cout << "Your first fraction: " << frac.getNumerator() << "/" << frac.getDenominator() << endl;
cout << "Your second fraction: " << frac2.getNumerator() << "/" << frac2.getDenominator() << endl;
  
  
return 0;
}
You're making your program harder than it really is.

Your reduce function should be like this:
1
2
3
4
5
6
7
8
9
10
11
double reduce(double num, double denom)
{
    int reducedNumber = 0;

    if (denom == 0)
        reducedNumber = num;
    else
        reducedNumber = fmod(num, denom);

    return reducedNumber;
}


Then just display what the reduced value of the fraction is..
cout << "Your fraction reduced is: " << frac.reduce(num, denom) << "." << endl;
One thing you could do is to add a friend function to define the << operator for the standard ostream.
1
2
3
4
5
    // Friend function to allow print to output stream
    friend std::ostream & operator<<(std::ostream & os, const Fraction & f)
    {
        return os << f.numerator << '/' << f.denominator;
    }

It returns a reference to the stream, to allow for chained output operations. Now you can do such things as:
1
2
3
4
    Fraction f1; 
    Fraction f2(-363, 99);
    
    cout << "f1: " << f1 << "  f2: " << f2 << endl;



As for the program code so far, there are a number of areas in need of attention.

The default constructor Fraction(){}; should assign some initial values to the numerator and denominator, I'd suggest 0/1. It should definitely ensure that the denominator is not zero.

The comparison operations appear mathematically unsound:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    Fraction a(3,4);
    Fraction b(6,8);
    Fraction c(1,2);
    Fraction d(1,8);
    
    if (a == b)
        cout << a << " is equal to " << b << endl;
    else
        cout << a << " is not equal to " << b << endl;
        
    if (c > d)
        cout << c << " is greater than " << d << endl;
    else
        cout << c << " is not greater than " << d << endl;

Output (currently incorrect):
3/4 is not equal to 6/8
1/2 is not greater than 1/8


The ++ and -- operators should, as stated in the original instructions, modify only the numerator.

As for the toDecimal() member function, it should not take any parameters, instead it should use the values of the current object. Likewise with toString(). reduce() likewise should use the values of the current object, which it should then modify, a private gcd() helper function might be useful.
Topic archived. No new replies allowed.