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);
Related
This question already has answers here:
What are the basic rules and idioms for operator overloading?
(8 answers)
Closed 6 years ago.
I am getting error while trying to compile the following code. I am beginner. Please help me figuring it out. I am trying to overload the operators _,+,/,*. It shows error while compiling. Should I use "friend" to solve this?
#include<stdio.h>
class complex{
private:
double real; //real part of complex
double imag; // imaginary part of complex
public:
complex(double r=0., double i=0.):real(r),imag(i)
{
} // constructor with initialization
complex(const complex&c):real(c.real),imag(c.imag)
{
} // copy constructor with initialization
~complex()
{
} // destructor
double re() const
{
return real;
} // read real part
double im() const
{
return imag;
} // read imaginary part
const complex& operator=(const complex&c)
{
real=c.real;
imag=c.imag;
return *this;
} //assignment operator
const complex& operator+=(const complex&c)
{
real += c.real;
imag += c.imag;
return *this;
} // addition of current complex
const complex& operator-=(const complex&c)
{
real -= c.real;
imag -= c.imag;
return *this;
} // subtract from current complex
const complex& operator*=(const complex&c)
{
double keepreal = real;
real = real*c.real-imag*c.imag;
imag = keepreal*c.imag+imag*c.real;
return *this;
} // multiply current complex with a complex
const complex& operator/=(double d)
{
real /= d;
imag /= d;
return *this;
} // divide current complex with real
void print(const complex&c)
{
printf("(%f,%f)\n",c.re(),c.im() );
} // printing complex number
friend complex operator !(const complex& c)
{
return complex(c.re(),-c.im());
}
friend double abs2(const complex& c)
{
return c.re()*c.re()+c.im()*c.im();
} // absolute value of complex
const complex& operator/=(const complex&c)
{
return *this *= (!c)/=abs2(c);
} // divide the current complex by a complex
const complex operator-(const complex& c)
{
return complex(-c.re(),-c.im());
} // negative of complex number
const complex operator-(const complex& c,const complex& d)
{
return complex(c.re()-d.re(),c.im()-d.im());
} // difference between complex numbers
const complex operator+(const complex& c,const complex& d)
{
return complex(c.re()+d.re(),c.im()+d.im());
} // addition of complex numbers
const complex operator*(const complex& c,const complex& d)
{
return complex(c)*=d;
} // multiplication of complex numbers
const complex operator/(const complex& c,const complex& d)
{
return complex(c)/=d;
} // division of complex numbers
};
int main(){
complex c(1.,0.),d(3.,4.);
print(c-d);
print(c/d);
return 0;
}
the output I am getting is:
complex_nums.cpp:76:59: error: ‘const complex complex::operator-(const complex&, const complex&)’ must take either zero or one argument
const complex operator-(const complex& c,const complex& d)
^
complex_nums.cpp:80:59: error: ‘const complex complex::operator+(const complex&, const complex&)’ must take either zero or one argument
const complex operator+(const complex& c,const complex& d)
^
complex_nums.cpp:84:59: error: ‘const complex complex::operator*(const complex&, const complex&)’ must take either zero or one argument
const complex operator*(const complex& c,const complex& d)
^
complex_nums.cpp:88:59: error: ‘const complex complex::operator/(const complex&, const complex&)’ must take exactly one argument
const complex operator/(const complex& c,const complex& d)
^
complex_nums.cpp: In function ‘int main()’:
complex_nums.cpp:96:11: error: ‘print’ was not declared in this scope
print(c-d);
^
complex_nums.cpp:97:9: error: no match for ‘operator/’ (operand types are ‘complex’ and ‘complex’)
print(c/d);
All your operators (+,-,*,/) need exactly one or no arguments, unless they are friend functions. Mark all the operator functions as friend, and the code should work. Otherwise, eliminate 1 parameter from each of the operators, and instead of that use the current instance (this). Example for + operator with parameter removed:
const complex operator+(const complex& c)
{
return complex(c.re()+re(),c.im()+im());
}
Reference of friend arithmetic operators: http://www.learncpp.com/cpp-tutorial/92-overloading-the-arithmetic-operators-using-friend-functions/
Next Error
What are you doing with your print() function? It should be in global scope, because it takes a complex as parameter. Move print() out of the class into global scope, like this. If you still want to keep a print() for the object itself, do so, but the one for your class should look like below:
class complex
{
void print(const complex&c)
{
printf("(%f,%f)\n",re(),im() );
} // printing complex number
};
void print(const complex&c)
{
printf("(%f,%f)\n",c.re(),c.im() );
} // printing complex number
Binary operators are either free functions with 2 arguments (preferred) or member functions with one argument (not so good).
You have defined member functions with 2 arguments.
Turning them into free functions by adding friend is one way.
Another is to make them free functions, defined outside the class but written in terms of member functions (as you have done anyway):
struct complex
{
/* ... */
};
// class definition ends
//free function
inline complex operator/(const complex& c,const complex& d)
{
return complex(c)/=d;
} // division of complex numbers
Note, this function can be improved:
inline complex operator/(complex c,const complex& d)
{
c /= d;
return c;
}
Also, unary operators should return complex&, not const complex&. The thing you're returning is mutable, because you just mutated it.
For the errors with the operators must take either zero or one argument, this is because you are implementing the non-member function as a member funciton. These should be free functions to work properly, or should only take one argument and use this as the other.
See this question for clarification:
Operator overloading : member function vs. non-member function?
For the error with print, I guess you are trying to call the print member function. To do that you need to do e.g. the following:
complex(c-d).print();
Suppose I have the following class:
class Point{
private:
int x,y;
public:
int get_x() const {return x;}
int get_y() const {return y;}
Point() :x(0),y(0){}
Point(int x,int y):x(x),y(y){}
Point(const Point& P){
x = P.get_x();
y = P.get_y();
}
Point& operator= (const Point& P) {
x = P.get_x();
y = P.get_y();
return *this;
}
friend ostream& operator<<(ostream& os,const Point& P) {
os<<"["<<P.get_x()<<", "<<P.get_y()<<"]";
return os;
}
Point operator - (const Point &P){
return Point(x-P.get_x(),y-P.get_y());
}
friend bool operator > (const Point &A, const Point &B) {
return A.get_y()>B.get_y();
}
};
Here I used friend function. I can also use function without friend:
class Point{
...
bool operator > (const Point &B) const {
return y>B.get_y();
}
...
};
What are the differences between them in actual implementations? Also in the second method, the code won't compile without 'cont', why is that? Even after I changed the getter function into non-const function, it still won't compile without the 'const'.
As you've already noticed, comparison operator overloads can either be implemented as a member function or as a non-member function.
As a rule of thumb you should implement them as a non-member non-friend function where possible, as this increases encapsulation, and it allows (non-explicit) conversion constructors to be used on either side of the operator.
Say for instance your Point class for whatever reason had an int conversion constructor:
Point(int x);
With a non-member comparison operator you can now do the following:
Point p;
p < 3; // this will work with both a member and non-member comparison
3 < p; // this will **only** work if the comparison is a non-member function
You also seem to be confused about when to use const, again as a rule of thumb for comparison operators you should always use const wherever possible, because comparisons logically do not involve any change to the object.
As Point is a very small class you could also take it by value instead, so in order of most to least preferable your options are:
// Non-member, non-friend
bool operator>(Point const& A, Point const& B);
bool operator>(Point A, Point B);
// Non-member, friend
friend bool operator>(Point const& A, Point const& B);
friend bool operator>(Point A, Point B);
// Member
bool Point::operator>(Point const& B) const;
bool Point::operator>(Point B) const;
This question already has an answer here:
simple c++: How to overload the multiplication operator so that float*myClass and myClass*float works
(1 answer)
Closed 9 years ago.
i'm trying write a polynomial class that can be used for calculation.
class Polynomial
{
public:
Polynomial(QString s); // creates a polynomial with QRegExp
const Polynomial operator+(Polynomial const& rhs); // NOT TESTED
const Polynomial operator+(double d);
const Polynomial operator-(Polynomial const& rhs); //
const Polynomial operator-(double d);
const Polynomial operator-();
private:
void resizeToMin();
QList<int> exp;
QList<double> coeff;
QChar var;
};
i would want to use the Polynomial like this:
Polynomial p("3*x^2 + x^1 -1");
double a = 2.0;
p = p*2 // this works
p = p*a // this works
p = 2*p // DOES NOT WORK
p = a*p // DOES NOT WORK
same for + and -
is this even possible? it would allow me to calculate with polynomials in the same way as with doubles
thanks in advance
Your operators only go one direction as you have them defined. As your class stands, you have the left side always be a Polynomial which won't work for double*Polynomial wherein the double is on the left side.
Since multiplication of polynomials is commutative (I think that's the word...a*b=b*a), you can define an operator like this outside the class:
Polynomial operator+(const double& lhs, const Polynomial& rhs) {
return rhs + lhs; //switch the operation so that the polynomial is on the left hand side
}
It will take in the double as the lefthand side and apply it as if it were the right hand side.
Adapted from this answer: https://stackoverflow.com/a/15741776/1124529
The linked answer also explains a little about doing operations if the operation is not commutative.
I have written a class for complex numbers in which I have overloaded the operator + and everything works fine, however I need to implement this as a non-member function and I am not sure how, or why there is a benefit of doing so.
Here is my code .h:
class Complex
{
private:
double a;
double b;
public:
Complex();
Complex(double aGiven);
Complex(double aGiven, double bGiven);
double aGetValue();
double bGetValue();
double operator[](bool getB);
Complex add(Complex &secondRational);
Complex operator+(Complex &secondRational);
}
.cpp:
Complex Complex::add(Complex &secondRational)
{
double c = secondRational.aGetValue();
double d = secondRational.bGetValue();
double anew = a+c;
double bnew = b+d;
return Complex(anew,bnew);
}
Complex Complex::operator+(Complex &secondRational)
{
return add(secondRational);
}
Any help on how to make these as non-member functions will be greatly appreciated!
Here is the addition operator outside of the class:
Complex operator+(const Complex& lhs, const Complex& rhs) {
//implement the math to add the two
return Complex(lhs.aGetValue() + rhs.aGetValue(),
lhs.bGetValue() + rhs.bGetValue());
}
Of course you will need to declare aGetValue() and bGetValue() as const:
double aGetValue() const {return a;}
double bGetValue() const {return b;}
The usual approach to arithmetic operations is to define the reflexive versions of the operators as members and the pure versions as non-members, implementing them with the reflexive versions:
class complex {
public:
const complex& operator+=(const complex& rhs) {
real += rhs.real;
imag += rhs.imag;
return *this;
}
};
complex operator+(const complex& lhs, const complex& rhs) {
complex res(lhs);
res += rhs;
return res;
}
How is explained above by pippin1289.
Why is explained below:
Imagine one need to use object of class as
Complex c3 = 5 + c1;// for c3 object c1's real part (a) added with 5
As C++ preserve order of operand. Compiler resolve above addition call as
5.operator+ (const Complex & other);// which is not possible
Hence, overload it via free function.
Your class is exposing necessary information via public interface such as aGetValue() and bGetValue.
Hence, this free overloaded + operator function need not be friend of class.
Additionally, Prefer non friend non member function over member function as it helps reduce degree of encapsulation.
This is explained here ==> http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197?pgno=1
You can declare a friend to your Complex class
class Complex {
// blah....
friend Complex operator+(Complex const& a, Complex const & b);
};
The overloaded operator can access the private members of Complex.
I'm wondering if you can overload an operator and use it without changing the object's original values.
Edited code example:
class Rational{
public:
Rational(double n, double d):numerator_(n), denominator_(d){};
Rational(){}; // default constructor
double numerator() const { return numerator_; } // accessor
double denominator() const { return denominator_; } // accessor
private:
double numerator_;
double denominator_;
};
const Rational operator+(const Rational& a, const Rational& b)
{
Rational tmp;
tmp.denominator_ = (a.denominator() * b.denominator());
tmp.numerator_ = (a.numerator() * b.denominator());
tmp.numerator_ += (b.numerator() * a.denominator());
return tmp;
}
I made the accessors const methods, but I'm still getting a privacy error for every tmp.denominator_ / numerator_.
Maybe I'm missing something, but why don't you just take out the code that modifies the arguments?
const Rational Rational::operator+(Rational& num)
{
Rational tmp;
tmp.denominator_ = (denominator_*num.denominator_);
//numerator_*=num.denominator_;
//num.numerator_*=denominator_;
tmp.numerator_ = (numerator_+num.numerator_);
return tmp;
}
This would be caught earlier by being const-correct.
That means your function signature should be this:
Rational Rational::operator+(const Rational& num) const
Then you will get errors because you are modifying const objects. The way your operators are written now is generally considered incorrect.
When you add 2 + 3, neither 2 nor 3 changes: they are const.
Edit
Sorry, I missed the actual math part. Here are a few things:
As a member function (what I have above), do this:
// Note that I use lhs and rhs to refer to the left-hand
// and right-hand sides of an operation. As a member function
// my left-hand side is implicitly `this`.
Rational Rational::operator+(const Rational& rhs) const
{
Rational temp;
temp.denominator_ = (denominator() * rhs.denominator());
temp.numerator_ = (numerator() * rhs.denominator());
temp.numerator_ += (denominator() * rhs.numerator());
return temp;
}
As a global function, do this:
Rational operator+(const Rational& lhs, const Rational& rhs)
{
Rational temp;
temp.denominator_ = (lhs.denominator() * rhs.denominator());
temp.numerator_ = (lhs.numerator() * rhs.denominator());
temp.numerator_ += (lhs.denominator() * rhs.numerator());
return temp;
}
The issue here is you'll get access violations: your member variables are private to the class. You need to let the compiler know that it is okay if this function handles your class's private variables by making the function a friend of the class:
class Rational
{
public:
friend Rational operator+(const Rational& lhs, const Rational& rhs);
}
What you're looking for are the "binary" addition and subtraction operators:
const Rational operator+(const Rational& A, const Rational& B)
{
Rational result;
...
return result;
}
update (in response to new code and comments):
You are getting that error because your accessor functions are not declared as constant functions, so the compiler has to assume that they might modify the original object. Change your accessors as follows, and you should be good to go:
double numerator() const { return numerator_; }
double denominator() const { return denominator_; }
update
To properly handle privacy issues, you should declare the binary operator+ function as a friend of the Rational class. Here is how it would look:
class Rational {
public:
Rational(double n, double d):numerator_(n), denominator_(d) {};
Rational() {}; // default constructor
double numerator() const { return numerator_; } // accessor
double denominator() const { return denominator_; } // accessor
friend Rational operator+(const Rational& A, const Rational& B);
private:
double numerator_;
double denominator_;
};
const Rational operator+(const Rational& a, const Rational& b)
{
Rational result;
result.denominator_ = (a.denominator_ * b.denominator_);
result.numerator_ = (a.numerator_ * b.denominator_);
result.numerator_ += (b.numerator_ * a.denominator_);
return result;
}
no .. you have to rewrite + and - .. it's not that hard. Then change the signatures to
const Rational Rational::operator+(Rational& num) const
const Rational Rational::operator-(Rational& num) const
that way the compiler will let you know if you are modifying your object.
Since your class already provides accessors to the numerator and denominator, and it has a public constructor, there is no need to use any friends. You can overload operator+ as follows:
const Rational operator+(const Rational& rhs, const Rational& lhs)
{
double newNumerator = rhs.numerator() * lhs.denominator() +
rhs.denominator() * lhs.numerator();
return Rational(newNumerator, rhs.denominator() * lhs.denominator());
}
In response to some of the other answers:
Everything about this question is exactly answered by Item 24 of Effective C++ (Third Edition). In this item, Scott Meyers shows that, in cases dealing with numerical types where you want to support implicit conversion in an intuitive manner, it is best to use a non-member non-friend function.
Say your Rational class had the following constructor:
Rational::Rational(double numerator = 0, double denominator = 1);
In this case, if operator+ were a member function, trying to do mixed mode arithmetic would work only half the time:
Rational oneHalf(1, 2);
oneHalf + 2; // works
2 + oneHalf; // error!
In the second example, operator+ for integers is called. The way to fix this is to make operator+ for Rationals a non-member function as shown above.
If you have access to Effective C++, you should also check out Item 23: Prefer non-member non-friend functions to member functions.
I prefer to implement operator+ in terms of operator+=. Then clients get to choose if they want a temp copy or not. Also operator+= is more natural as a member function so it has access to the private parts.
class Rational {
public:
Rational(double n, double d):numerator_(n), denominator_(d) {};
Rational() {}; // default constructor
double numerator() const { return numerator_; } // accessor
double denominator() const { return denominator_; } // accessor
Rational & operator+=(const Rational& b) {
denominator_ *= b.denominator_);
numerator_ *= (b.denominator_);
numerator_ += (b.numerator_ * denominator_);
return *this;
}
private:
double numerator_;
double denominator_;
};
const Rational operator+(const Rational& a, const Rational& b)
{
Rational result(a);
result += b;
return result;
}
However the easiest way to implement operator overloading is to use the boost operators library. Then you implement the minimum set of operators and boost take care of the rest and all the gotchas (including wintermute's example of 2 + oneHalf.