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.
2 Answers 2
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;
}
7 Comments
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.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;
}
operator*?