Search code examples
c++classoperator-overloadingprivate-membersfractions

Adding fractions by overloading + operator using Class with Private Data Members


First of all this is a Homework assignment. I just need some help solving an issue related to the Fraction operator+() function. It is supposed to add together two fractions from an array in the function BinarayMathTest, but the Fraction::operator+() function only returns the denominator.

#include <iostream>
#include <string>

using namespace std;



class Fraction
{
    private:
    int num,denom;
    public:

    Fraction operator + (const Fraction &right)const;

    friend ostream&operator<<(ostream&stream,Fraction obj);
    Fraction(int a=0,int b=1){num=a; denom=b;}

};

ostream&operator<<(ostream&stream,Fraction obj)
{
    stream<<obj.num<<'/';
   stream<<obj.denom;
   return stream;
}

Fraction Fraction::operator+(const Fraction &right)const
{
    Fraction temp;
    Fraction tempo;
    Fraction full;
    temp.num = ((num*right.denom) + (right.num*denom));
    tempo.denom =(denom*right.denom);
    full = (temp,tempo);
    return full;
}


void BinaryMathTest();


int main()
{

    BinaryMathTest();

    return 0;
}



void BinaryMathTest()
{
    cout << "\n----- Testing binary arithmetic between Fractions\n";

    const Fraction fr[] = {Fraction(1, 6), Fraction(1,3),
                       Fraction(-2,3), Fraction(5), Fraction(-4,3)};

    for (int i = 0; i < 4; i++) {
          cout << fr[i] << " + " << fr[i+1] << " = " << fr[i] + fr[i+1]
<<endl;}}



/* OUTPUT
----- Testing binary arithmetic between Fractions
1/6 + 1/3 = 0/18
1/3 + -2/3 = 0/9
-2/3 + 5/1 = 0/3
5/1 + -4/3 = 0/3
*/

Solution

  • Fraction::operator+() function only returns the denominator.

    Let's follow the lines of code in that function and see what happens.

    Fraction temp;  // Creates an object with num = 0, denom = 1
    Fraction tempo; //    ditto
    Fraction full;  //    ditoo
    
    temp.num = ((num*right.denom) + (right.num*denom)); // Sets the num of temp
    
    tempo.denom =(denom*right.denom);  // Sets the denom of tempo
    

    I have a feeling you don't know happens in the next line.

    full = (temp,tempo);
    

    The RHS of the line is a expression that uses the comma operator.

    It evaluates temp and discards the value. It evalutes tempo and assigns it to full. After that line, full has only the denominator since the numerator of tempo was never changed from 0.

    // Returns an object whose numerator is zero.
    return full;
    

    You can simplify that function to:

    Fraction Fraction::operator+(const Fraction &right)const
    {
       int num = ((num*right.denom) + (right.num*denom));
       int denom = (denom*right.denom);
    
       return Fraction(num, denom);
    }
    

    One thing to note in the above implementation is that it will quickly increase the values of num and denom if you keep adding Fraction objects. You can delay/prevent integer overflow, you'll have to reduce num and denom to smaller values by dividing both by their GCD.

    Fraction Fraction::operator+(const Fraction &right)const
    {
       int num = ((num*right.denom) + (right.num*denom));
       int denom = (denom*right.denom);
       int gcd = get_gcd(num, denom);
    
       return Fraction(num/gcd, denom/gcd);
    }