Massassi Forums Logo

This is the static archive of the Massassi Forums. The forums are closed indefinitely. Thanks for all the memories!

You can also download Super Old Archived Message Boards from when Massassi first started.

"View" counts are as of the day the forums were archived, and will no longer increase.

ForumsDiscussion Forum → C++ Help: Overloading operators
C++ Help: Overloading operators
2009-09-20, 12:27 PM #1
I'm taking a class right now that requires that I know C++, but unfortunately the only programming language I've used is a little bit of C. For my first homework assignment I have to write a data type for rational numbers. Well, I have to override the += operator to add two rational numbers, like so:

rational1 += rational2;

Because you override += operator as a member function, your only parameter is a const pointer to rational2. The thing is, I need to pass both rational 1 and rational2 to a non-member function to get the denominators equal before they can be added. I'm not really sure how to pass rational1 due to the way I'm accessing it. Unfortunately everything I've turned up in my text book and Google consider this too elementary to bear mention. This is what i have so far:

Code:
void rational::operator +=(const rational& second_rational){
     equalizeDenominator(rational, second_rational);
     numerator = numerator + second_rational.numerator;
}


Any help would be greatly appreciated!
2009-09-20, 1:03 PM #2
equalizeDenominator is going to be unable to modify second_rational being as it's const. (Incidentally the answer to the question you actually asked is '*this'.)

Why do you need this function at all? Try this.

Code:
rational& rational::operator+=(const rational& rhs)
{
      this.numerator =  (this.numerator * rhs.denominator) + (rhs.numerator * this.denominator);
      this.denominator *= rhs.denominator;
      this.reduce();
      return *this;
}
2009-09-20, 1:40 PM #3
Originally posted by Obi_Kwiet:
The thing is, I need to pass both rational 1 and rational2 to a non-member function to get the denominators equal before they can be added.
C = A + B should not be changing the values of A and B. That kind of side effect is horrific.
2009-09-20, 1:47 PM #4
Well, the reason I use equalizeDenominator is that I need it for a bunch of other stuff in the class, so it's really handy to just be able to call. Would it be possible to pass second_rational by value instead?

Thanks for the help!

Originally posted by Jon`C:
C = A + B should not be changing the values of A and B. That kind of side effect is horrific.


Well, since it's A += B, I need to change A, but leave B alone.
2009-09-20, 1:59 PM #5
equalizedenominator is guaranteed to never need to change B?
2009-09-20, 2:00 PM #6
Quote:
Well, the reason I use equalizeDenominator is that I need it for a bunch of other stuff in the class, so it's really handy to just be able to call. Would it be possible to pass second_rational by value instead?

You could pass it into operator+= by value, yes. Passing it by value to EqualizeDenominator would be rather pointless.
2009-09-20, 2:02 PM #7
I would do something like this to avoid the problem Jon`C mentions:

Code:
void rational::operator +=(const rational& second_rational){
     // Get the Least Common Multiple of the denominators
     int newdenom = getDenominatorsLCM(this, second_rational);

     // Convert to a multiplier so we can scale the numerator
     double scale = newdenom / denominator;

     // Scale the value to the new LCM denominator
     denominator = newdenom;
     numerator *= scale;

     // Scale the other numerator and add it.
     numerator += second_rational.numerator * newdenom / second_rational.denominator;
}


JM's might be better though since it's entirely integer math.

2009-09-20, 2:12 PM #8
Originally posted by Jon`C:
equalizedenominator is guaranteed to never need to change B?


Well, if I pass it by value, do I care if it changes B?

The whole point of using the function equalizeDenominator, is that I have to do that operation 8 or 10 times throughout the class, so I thought that it would be easier if I could just call a function instead of have that bit of code in every function that used it. Is that bad practice?

MZZter, that's very similar to the way I did it, only the first four lines are in the function equalizeDenominator, and I reduce the fraction.
2009-09-20, 2:25 PM #9
Originally posted by Obi_Kwiet:
Well, if I pass it by value, do I care if it changes B?
Are you passing it by value? From the code you posted you're passing secondrational, which is a reference and is probably preserved as a reference by equalizedenominator because there's no other apparent way of getting information back out of it.
2009-09-20, 2:32 PM #10
That's why I asked if I could pass by value instead of pass by reference. Would that work better?
2009-09-20, 2:37 PM #11
No because the new value of second_rational.numerator will be lost, and you need it to add to your current rational number. You'd have to make a complete copy of second_rational for your method to work, or you can just use one of ours. :P

2009-09-20, 2:44 PM #12
But that's what pass by value does, right?

Code:
void rational::operator +=(rational second_rational)


And then pass to the equalizeDenominator by reference.
2009-09-20, 2:58 PM #13
Originally posted by Obi_Kwiet:
But that's what pass by value does, right?


Yes, you can do it that way. Just so you know, though, operator+= should also return a value (a rational) so its use mirrors that of integral types.
2009-09-20, 3:48 PM #14
What the **** is this, ignore JM day?
2009-09-20, 6:20 PM #15
:confused:
2009-09-21, 8:39 PM #16
It works!

I'm still probably going to drop the class though. I need to focus on my major classes and I can't just hope that I'll always be able to get everything done. Programming assignments throw a huge wrench into that. Thanks for all the help guys!
2009-09-21, 9:31 PM #17
CS is a ball.
2009-09-21, 9:49 PM #18
Indeed Jon`C. I had one class with only ONE other guy. The hardest part of the class was helping him with his own code (I suck at teaching/explaining things). I would do most of my homework programs right after class, took me an hour for the simple ones at most.

Originally posted by Obi_Kwiet:
But that's what pass by value does, right?


Except when you pass by value, the ORIGINAL is not changed. So your code wouldn't work because you'd be using the original second_rational's numerator, not the copy's changed one.

2009-09-21, 10:00 PM #19
Originally posted by Jon`C:
CS is a ball.


Yeah, if all my classes were like these I'd be living it up. This is the first homework we've had all year. The trouble is, I have a bunch of really difficult electrical classes that already push the limit pretty consistently, so it's really more of a time issue. A big programming project with my programming abilities at the wrong time could mess everything up. I have no doubt I could get it all done pretty easily given a reasonable amount of time, but I don't have that.

Quote:
Except when you pass by value, the ORIGINAL is not changed. So your code wouldn't work because you'd be using the original second_rational's numerator, not the copy's changed one.


That's the idea. It worked when it changed it to be pass by value. The operator overload is being passed by value, the equalizeDenominator function is passed to by reference.

↑ Up to the top!