I have a small error with operator overloading that's been bugging me.
I've got a class:
class Fraction{
private:
//Variables
int numerator;
int denominator;
//Constructor
public:
//Methods
Fraction();
Fraction(int, int);
};
I also have this operator overloading function:
Fraction& operator+=(const Fraction& f);
It seems like it would build fine to me, but the compiler is giving me this error message:
In file included from Fraction.cpp:3:
./Fraction.h:31:11: error: overloaded 'operator+=' must be a binary operator
(has 1 parameter)
Fraction& operator+=(const Fraction& f);
^
1 error generated.
Every single example of += I've seen so far is identical to what I'm doing as far, from what I can tell. If someone could point out my stupidity, that would be great!
Either declare the operator as a member function of the class or if it is a non-class function then it shall have two parameters
For example
1 member function
class Fraction
{
private:
//Variables
int numerator;
int denominator;
//Constructor
public:
//Methods
Fraction();
Fraction(int, int);
Fraction& operator +=( const Fraction &rhs );
};
2. non-member function
class Fraction
{
private:
//Variables
int numerator;
int denominator;
//Constructor
public:
//Methods
Fraction();
Fraction(int, int);
friend Fraction& operator +=( Fraction &lhs, const Fraction &rhs );
};
Fraction& operator +=( Fraction &lhs, const Fraction &rhs ) { /* some code */ }
Take into account that then the operator is a non-class function you may not use this
Also the non-class operator should be a friend function of the class if there is no public access to corresponding data members through getters and setters.
You should put
Fraction& operator+=(const Fraction& f);
declaration inside class if it has to be binary operation. Alternatively you can declare this operator in global namespace taking two instances of Fraction, but make it friend of this class (as it needs access to private data) by declaring friendship in Fraction through:
friend Fraction& operator+=( Fraction& l, const Fraction& r);
You are defining a free function, it should have 2 parameters (binary operator).
Declare it inside the Fraction class instead.
If you overload the operator as a non-member function you need to write it like this
Fraction& operator+=(const Fraction& lhs, const Fraction& rhs);
This errors occurs when your overloaded operator is outside your class as global.
You should try give declaration of this operator into your class as:
Fraction& operator+=(const Fraction& f);
You can leave as you did but then you must change operator to this:
Fraction& operator+=(const Fraction& f, const Fraction& g);
Here you can find some more information in my post
Related
Class fraction
{
public:
fraction operator+ (const fraction& fr) const;
private:
int num; //numerator
int den; //denominator
};
I wanted to overlaod the operator+ so that it perfoms the multiplication of an integer constant (calling object) and a fraction.
fraction fraction::operator+ (const fraction& fr) const
{
fraction result;
result.num = fr.num + fr.den * (*this);
//error message says invalid operands to binary exprssion ('int' and 'constant fraction')
result.den = fr.den;
simplified_fr(result); // a helper function to simplify the resulted fraction
return result;
}
It seems that the problem is about the type of calling object. I intended to make it a constant integer but the computer thought it was a 'const fraction'. Can someone please advise me why this happened and how can I fix it? Thank you in advance!!!
I assume you would like to do achieve something like this:
fraction fract;
fraction fract2 = 2 + fract;
The answer is that you cannot overload member method operator+ for non-class objects. BUT you can define/overload global operator+ function:
fraction operator+(int num, const fraction& rFrac)
{
//your implementation
}
You will probably need access to private members of fraction class. That can be acomplished by making operator+ a friend:
class fraction
{
//...
friend fraction operator+(int num, const fraction& rFrac);
//...
}
So I am trying to overload the operator* so both ways will work:
Myclass * a;
a * Myclass;
When I declare this function everything goes well:
Polynomial operator*(const double d);
But when I try doing it the other direction like this:
Polynomial operator*(Polynomial &, const double d)
I'm getting an error: "too many parameters for this operator function.
What am I doing wrong?
Thanks!
When you overload a binary operator as a member function, the class instance is always the left-hand operator and the argument to the function is the right hand, there's nothing you can do to change it. Not if you want to continue using member only functions.
But if you use a global non-member function you can easily have whichever order you want. For example
class Polynomial { ... };
// Function that allows poly * 12.34
Polynomial operator*(const Polynomial& lhs, const double rhs)
{
...
}
// Function which allows 12.34 * poly
Polynomial operator*(const double lhs, const Polynomial& rhs)
{
...
}
And if you don't want to reimplement the same code in both functions, and the operator is commutative (like multiplication and addition should be) then you can implement one of the function by calling the other:
Polynomial operator*(const Polynomial& lhs, const double rhs)
{
...
}
Polynomial operator*(const double lhs, const Polynomial& rhs)
{
return rhs * lhs; // Calls the operator function above
}
Of course, the operator taking the Polynomial object as left-hand side may of course be implemented as a member function.
On a related note, if you have implemented the operator as a member function, e.g.
class Polynomial
{
...
Polynomial operator*(const double rhs)
{
...
}
};
The the following code
Polynomial poly1(...);
Polynomial poly2 = poly * 12.34;
is equal to
Polynomial poly1(...);
Polynomial poly2 = poly.operator*(12.34);
I am trying to make program that uses operator overloading to do basic math operations on rational numbers. I keep getting an errors in the functions where it says i must have an arithmetic of enum type. Also I get an error istream where it says that the numerator and denominator are undefined.
Here is the header file:
#ifndef rational_H
#define rational_H
#include <iostream>
using namespace std;
class Rational
{
friend ostream & operator<<(ostream & , const Rational &);
friend istream & operator<<(istream & , const Rational &);
public:
// default constructor
Rational(int = 0, int = 1);
// overload operators for "normal" operation
Rational operator+(const Rational&);
Rational operator-(const Rational&);
Rational operator*(const Rational&);
Rational operator/(const Rational&);
operator double();
// overload relational operators for "normal" operation
bool operator>(const Rational&) const;
bool operator<(const Rational&) const;
bool operator>=(const Rational&) const;
bool operator<=(const Rational&) const;
bool operator==(const Rational&) const;
bool operator!=(const Rational&) const;
protected:
int *numerator;
int *denominator;
void reduction(void);
};
#endif
// this part of code is from my rational cpp file//
// default constructor//
Rational::Rational( int n, int d )
{
*numerator =1 ;
// sets numerator
if(d == 0)
d = 1; // If denominator is zero then set to one.
*denominator = 0;
// sets denominator
reduction(); // store the fraction in reduced form
}
// all the other operators have the same error as well//
Rational Rational::operator-(const Rational&a)
{
Rational sub;
sub.numerator = *this->numerator * a.denominator -//the error is with the 'a'needs to be an arithmetic type or enum type//
*this->denominator * a.numerator;
sub.denominator = *denominator * a.denominator;
sub.reduction();
return sub;
}
//also the istream part has an error where the denominator and numerator is underfined as well//
istream& operator >> ( istream& inputStream, Rational& rnum )
{
inputStream>>rnum.*numerator;//numerator and denmoinator undefined for some reason//
inputStream.ignore(1);
inputStream>>rnum.*denominator;
return inputStream;
}
There are multiples small errors in your code.
First of all you should not be using pointers for these members, it does not bring any advantages.
But as you chose this way, you have to dereference them each time you want to read or update them, which hasn't be done in your operator- implementation, and incorrectly in your operator>> implementation (the asterisk needs to be put before the whole expression).
Next error in the code you provided, you marked as friend operator<<(istream & , const Rational &) in your class definition, but it should have been operator>>. And this declaration needs to match the definition that appears next (i.e., remove the const of the second argument, which obviously has to be mutated).
And, last but not least, the undefined behavior caused by all the dereferencing of you uninitialized pointers…
This is probably a copy and past error. The line
friend istream & operator<<(istream & , const Rational &);
should be
friend istream & operator>>(istream & , Rational &);
Your implementation later on in the file has:
istream& operator >> ( istream& inputStream, Rational& rnum )
{
...
}
It matches the second declaration, not the first one.
I'm implementing a c++-class representing a fraction. Here goes my code.
class Fraction
{
public:
Fraction(char i);
Fraction(int i);
Fraction(short i);
Fraction(long int l);
#ifdef __LP64__
Fraction(long long l);
#endif
Fraction(float f);
Fraction(double d);
Fraction(double x, double y);
Fraction operator +() const;
Fraction operator -() const;
Fraction& operator +=(const Fraction& other);
Fraction& operator -=(const Fraction& other);
Fraction& operator *=(const Fraction& other);
Fraction& operator /=(const Fraction& other);
bool operator ==(const Fraction& other);
bool operator !=(const Fraction& other);
bool operator >(const Fraction& other);
bool operator <(const Fraction& other);
bool operator >=(const Fraction& other);
bool operator <=(const Fraction& other);
operator double();
operator float();
static void commonize(Fraction& a, Fraction& b);
void shorten();
double getNumerator();
double getDenominator();
friend Fraction operator +(Fraction const& a, Fraction const& b);
friend Fraction operator -(Fraction const& a, Fraction const& b);
friend Fraction operator *(Fraction const& a, Fraction const& b);
friend Fraction operator /(Fraction const& a, Fraction const& b);
friend ostream& operator <<( ostream& o, const Fraction f);
protected:
double numerator, denominator;
};
I now have two little problems.
Now trying to call
Fraction a(1, 2);
cout << (3 + a) << endl;
simply results in this error:
fractiontest.cpp:26: error: ambiguous overload for ‘operator+’ in ‘3 + a’
fractiontest.cpp:26: note: candidates are: operator+(int, double) <built-in>
fractiontest.cpp:26: note: operator+(int, float) <built-in>
All I'd really want is this:
explicit operator double();
explicit operator float();
But apparently, this doesn't work. I'd like these two cast-operators to be called iff I use the cast notation. For example Fraction f(1, 2); double d = (double)(f);
By definition the conversion operators are implicit. You can't make them explicit.
The normal solution is named member functions to do the conversion. I think you could also create a specialized template method that would look just like a static_cast and call through to the explicit class method.
Remove the conversion operators and 3 + a should use your friend operator+ while implicitly converting 3 to Fraction via the implicit constructor Fraction(int i);.
Edit: On the case of the explicit conversion operators, C++0x specifically allows this:
12.3.2 [class.conv.fct] p2
A conversion function may be explicit, in which case it is only considered as a user-defined conversion for direct-initialization.
The C++03 standard doesn't specifically mention this.
So I have a LongInt class that will have new definition for the + and * operators. The initialization in the header file looks like:
friend LongInt operator+(const LongInt& x, const LongInt& y);
friend LongInt operator*(const LongInt& x, const LongInt& y);
however in my implementation file, where I'm defining the methods found in the header, VS doesn't recognize the operator+ function or the operator* function as being listed in the header. I'm using the code:
friend LongInt LongInt::operator+(const LongInt& x, const LongInt& y)
{
}
and
friend LongInt LongInt::operator*(const LongInt& x, const LongInt& y)
{
}
Any ideas as to why this code wont work when I'm trying to define the operators?
The friend keyword is only used when declaring or defining the operator inside of a class; when declaring the operator as a friend inside of the class and defining it elsewhere, friend is only used on the declaration, not the definition. Also, functions declared as friend inside a class are in fact free functions in namespace scope, not class members. So, your definitions should look more like:
LongInt operator +(LongInt const& x, LongInt const& y) { /*...*/ }
LongInt operator *(LongInt const& x, LongInt const& y) { /*...*/ }
For further reading material, read over the following page: C++ FAQ: Friends
You're overriding an operator ... you "call" it using the operator:
LongInt foo;
LongInt bar;
LongInt foobar = foo + bar;