2

What I am trying to do here is to overload the % operator so it multiplies the numerator by an given number. All of my other overloaded operators in the program work perfectly, but this one is giving me problems. To isolate this issue, I created a separate smaller program with only this overloaded operator.

From the modu.h file (some hopefully irrelevant parts omitted):

class fraction {
 private:
 int numerator, denominator;
 public:
 fraction ();
 fraction (int n, int d);
 void print ();
 void operator% (int x);
};
// the constructors and print functions work fine for the other overloaded
// operators so I decided to omit them
void fraction::operator%(int x) {
 numerator = numerator * x;
}

When I use them in the main.cpp file like this

fraction frct (2, 3); // declare a fraction with a value of 2/3
frct = frct % 3;

I get these errors

modu.cpp:9:17: error: no match for ‘operator=’ in ‘frct = frct.fraction::operator%(3)’
modu.cpp:9:17: note: candidate is:
In file included from modu.cpp:3:0:
modu.h:6:7: note: fraction& fraction::operator=(const fraction&)
modu.h:6:7: note: no known conversion for argument 1 from ‘void’ to ‘const fraction&’

And when I use it like " frct = frct.%(3); ", I get the error:

modu.cpp:9:15: error: expected unqualified-id before ‘%’ token

I have checked over this several times for missing semicolons and curled brackets, but everything seems like it should be in order, and the operator% function does not look any different from my working overloaded operators.

asked Apr 28, 2013 at 8:24
1
  • 4
    Why wouldn't you just overload operator*? Commented Apr 28, 2013 at 8:24

2 Answers 2

3

You don't have a return value in the overloaded operator function. Do it like this:

fraction & fraction::operator% (int x) {
 numerator = numerator * x;
 return *this;
}

Also, since you are actually changing the value of the object, maybe it would be less confusing to use a different operator, like %= ?

EDIT: Seeing how you actually use the operator (assigning the result back to the object) i think it would be better if it actually didn't alter the object and instead created a new instance with the result, like this:

fraction fraction::operator% (int x) const {
 fraction result(*this);
 result.numerator = numerator * x;
 return result;
}
answered Apr 28, 2013 at 8:25
Sign up to request clarification or add additional context in comments.

7 Comments

While correct, the semantics of this are off the weirdness charts imo.
@chris I hope it's better now.
Detheroc's solution works perfectly, however, I eliminated the "&" between the "fraction & fraction". Many thanks.
The second solution is good. The first one is wrong - it modifies the original value, it's like a = b % 5 using integers would modify b, which is not what you expect - doing things that are unexpected is definitely never a good idea.
@Jäger, I'm still confused. Multiplying a fraction by a scalar is a perfectly fine operation, and it's what you're doing here. So why on earth is it using the modulus operator instead of the multiplication operator?
|
2

Firstly, unless you hate the people who will be maintaining your code, you should call multiplication * not %. I'll use * in my answer.

When overloading arithmetic operators, there are two forms to consider:

  • The assignment form, a *= b, which modifies the left operand. That's more or less what your overload is.
  • The normal form, a = b * c, which returns a new value without modifying either operand. That's how you're trying to use your overload.

The assignment form is generally a member function, and by convention it returns a reference to the modified object; this allows you to use it in complex expressions like a = (b *= c). It would look something like:

fraction & fraction::operator*=(int x) {
 numerator = numerator * x;
 return *this;
}

Once you've got that, one simple way to implement the normal form is by copying one argument and applying the assignment form to it. An advantage of this approach is that it doesn't need to be a member or a friend, as long as operator*= is public:

fraction operator*(fraction f, int x) {
 return f *= x;
}
answered Apr 28, 2013 at 10:44

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.