0

Part of my assignment is to use my professor's .cpp file. In it, I should be able to handle A = A + B where A and B are two fractions.

&Fraction Fraction::operator+(Fraction b)
{
  num = (num * b.denom) + (num * denom);/////// 
  denom = (denom * b.denom);
  if ((num * denom) >= 0) 
{ 
  sign_factor = 1;
}
else
{
  sign_factor = -1;
}
num = sign_factor * abs(num);
denom = sign_factor * abs(denom);
num = (num / (static_cast<double>(find_gcd(num, denom))));
denom = (denom / (static_cast<double>(find_gcd(num, denom))));
return this;
}

My question is how I would return the object A so that main.cpp can perform member assignment (assigning the result of A+B to A). Also, is it correct that I referred to num inside this function, or should I use a.num. For example, should it be "a.num = sign_factor * abs(num) or is what I have okay?

Thankyou very much!!

Kevin Cheng
  • 115
  • 1
  • 4
  • `operator+` should not return a reference, but a new object. You need `Fraction operator+(Fraction b) const;`. Create a new `Fraction` in the body and return it. – juanchopanza Oct 23 '14 at 10:24
  • mhmmm thats a great suggestion. ty – Kevin Cheng Oct 23 '14 at 10:26
  • See [operator overloading](http://stackoverflow.com/questions/4421706/operator-overloading) (although I disagree with some of the implementation details therein). – juanchopanza Oct 23 '14 at 10:27
  • Would Marco's idea also work? – Kevin Cheng Oct 23 '14 at 10:28
  • It depends what you mean by work. `A + B` should not modify `A`, so I would say it doesn't work at all. – juanchopanza Oct 23 '14 at 10:29
  • @KevinCheng: Yes, but change this to `operator+=`. Then you can write `+` as a non-member `Fraction operator+(Fraction x, Fraction const & y) {return x += y;}` – Mike Seymour Oct 23 '14 at 10:29
  • Oh, in my Professor's main.cpp the code reads: A = A + B. Why shouldn't it modify A? Sorry for the questions! I appreciate your help :P Slow learner here – Kevin Cheng Oct 23 '14 at 10:29
  • @KevinCheng: `A = whatever` should modify `A`; it's `A + B` that shouldn't. – Mike Seymour Oct 23 '14 at 10:31
  • Wait, @MikeSeymour, I can't modify my professor's main.cpp. Does this mean there is no point in doing so, or am I not understanding correctly? – Kevin Cheng Oct 23 '14 at 10:31
  • @KevinCheng: There should be no need to change the professor's `A = A + B`. I'm saying that you should implement `operator+` so that it doesn't modify its operands. That is, for example, `C = A + B` should change `C`, but not `A`. With your implementation, it would also change `A`. – Mike Seymour Oct 23 '14 at 10:34
  • I think I understand you @MikeSeymour. If i did it my way, would I still get the intended results? Are you telling me to do it your way for formality reasons or because of actual output results? Thanks – Kevin Cheng Oct 23 '14 at 10:37
  • @KevinCheng: You'd get the intended results; but also a surprising side-effect when `C = A+B` modifies `A`. This will lead to bugs if people (reasonably) expect `+` to give a new value, leaving its arguments unchanged, as the built-in operator does. – Mike Seymour Oct 23 '14 at 10:40

1 Answers1

0

This signature makes no sense:

&Fraction Fraction::operator+(Fraction b)

I don't know the purpose of your code but in a = a + b it might make sense to create a temporary with the result and return it

class Fraction {
public:
    Fraction operator+(Fraction b) const // Return a Fraction object
    {
        Fraction result;
        // ... initialize result...
        return result;
    }
};

if num is defined as a member variable of your Fraction class (or one of its subclasses) you can safely use it as you did or as this->num


Edit:

In regard to your comment, I'm adding some code to explain why returning a temporary object might make more sense. Compare the two versions and decide which one suits your needs better. Intuitively the first one is the preferred and most logical choice.

  • Version 1: returning a temporary (a doesn't get modified)

    class Fraction {
    public:
    
        Fraction operator+(Fraction& b)
        {
            Fraction result;
            result.num = num + b.num;
    
            return result;
        }
    
        void operator=(Fraction& b)
        {
            num = b.num;
        }
    
        int num;
    };
    
    
    int main()
    {
    
        Fraction a, b, c;
        a.num = 10;
        b.num = 20;
        c.num = 0;
    
        c = a + b;
        // a is now 10
        // b is now 20
        // c is now 30
    }
    
  • Version 2: returning a reference and modifying a

    class Fraction {
    public:
    
        Fraction& operator+(Fraction& b)
        {
            num = num + b.num;
    
            return *this;
        }
    
        void operator=(Fraction& b)
        {
            num = b.num;
        }
    
        int num;
    };
    
    
    int main()
    {
    
        Fraction a, b, c;
        a.num = 10;
        b.num = 20;
        c.num = 0;
    
        c = a + b;
        // a is now 30 <- I believe you don't want this
        // b is now 20
        // c is now 30
    }
    
Marco A.
  • 43,032
  • 26
  • 132
  • 246
  • That doesn't make any sense either. – juanchopanza Oct 23 '14 at 10:24
  • Thanks! This won't return a dangling reference correct? Because a and B will still be defined in main and won't go out of scope until the terminating brace in main? – Kevin Cheng Oct 23 '14 at 10:25
  • Although returning a reference from `operator+` doesn't make much sense either. Unless it does something other than addition, it needs to return a new object, leaving its operands unchanged. This is more like `operator+=`. – Mike Seymour Oct 23 '14 at 10:25
  • I ignore the purpose of his code but I suppose a temporary might make sense here – Marco A. Oct 23 '14 at 10:30
  • @KevinCheng I took a second look and it makes sense to create a temporary value, initialize it with the results of `a + b` and then return it. `a + b` isn't necessarily `a` unless you meant to mimic `operator+=` behavior as Mike wrote. – Marco A. Oct 23 '14 at 10:32
  • Can you please explain why a+b isn't necessarily a? I dont understand. – Kevin Cheng Oct 23 '14 at 10:34
  • @KevinCheng Edited the post, take a look at which behavior you want to implement and pay attention to `a` being modified or not – Marco A. Oct 23 '14 at 10:40