When I try to over load an operator "!", it gives error as following.
complex_nums.cpp: In function ‘complex operator!(const complex&)’:
complex_nums.cpp:50:23: error: passing ‘const complex’ as ‘this’ argument discards qualifiers [-fpermissive]
return complex(c.re(),-c.im());
^
complex_nums.cpp:14:9: note: in call to ‘double complex::re()’
double re(){
^
complex_nums.cpp:50:31: error: passing ‘const complex’ as ‘this’ argument discards qualifiers [-fpermissive]
return complex(c.re(),-c.im());
^
complex_nums.cpp:17:9: note: in call to ‘double complex::im()’
double im(){
^
The code is:
#include<iostream>
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(){
return real;
}; // read real part
double im(){
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(){
std::cout<<"Real: "<<re()<<" Imaginary: "<<im()<<"\n";
};
friend complex operator !(const complex& c){
return complex(c.re(),-c.im());
};
};
int main(){
complex C(1.,1.);
complex P(3.,2.);
C.print();
P.print();
P+=C;
P.print();
P=!C;
P.print();
return 0;
}
This is the clue...
error: passing ‘const complex’ as ‘this’ argument discards qualifiers
The problem is that im() and re() are not const methods.
Declare these functions with the qualifier const
double re() const {
return real;
}; // read real part
double im() const {
return imag;
}; // read imaginary part
because at least in the operator
friend complex operator !(const complex& c){
return complex(c.re(),-c.im());
};
they are called for a constant object.
This is rule that when you create const function , function which is passed to this const function, must be also const.. re() and im() must be const
Related
I'm writing a header file to learn more about operator overloading in C++, and I got the following error while implementing the division method for two complex numbers.
Here is the source code:
#ifndef __COMP_H
#define __COMP_H
#include <iostream>
class Complex{
private:
double real;
double imag;
public:
//constructor
Complex(double r=0, double i=0){real = r; imag = i;}
//operator overloading
Complex operator + (Complex const &obj){
Complex res;
res.real = real + obj.real;
res.imag = imag + obj.imag;
return res;
}
Complex operator - (Complex const &obj){
Complex res;
res.real = real - obj.real;
res.imag = imag - obj.imag;
return res;
}
Complex operator * (Complex const &obj){
Complex res;
res.real = real*obj.real + (-1)*imag*obj.imag;
res.imag = real*obj.imag + imag*obj.real;
return res;
}
Complex operator * (double const i){
Complex res;
res.real = i*real;
res.imag = i*imag;
return res;
}
Complex operator / (Complex const &obj){
Complex conj(obj.real, (-1)*obj.imag);
Complex res = (*this)*obj; //numerator
Complex den = obj*conj; //denominator, it will be 0 as it's imaginary value
res = res*(1/den.real); //multiply it with a scalar value
return res;
}
void print(){
std::cout << real << " + " << imag << "j\n";
}
};
#endif
and the error looks as follows
In file included from main.cpp:2:
comp.h: In member function 'Complex Complex::operator/(const Complex&)':
comp.h:52:27: error: passing 'const Complex' as 'this' argument discards qualifiers [-fpermissive]
Complex den = obj*conj; //denominator, it will be 0 as it's imaginary value
^~~~
comp.h:32:13: note: in call to 'Complex Complex::operator*(const Complex&)'
Complex operator * (Complex const &obj){
^~~~~~~~
I've seen other answers on stackoverflow but did not understand it, what is meant by this error and how to fix it? Thanks!
This
Complex operator - (Complex const &obj) { ...
and others are non-const member functions. Member functions are non-const by default, meaning they are declared to modify this. You cannot call them on a const instance. Most of your operators do not modify this, hence should be declared as const:
Complex operator - (Complex const &obj) const { ...
// ^^
In order to become more familiar with C++, I'm implementing a class to manipulate complex numbers.
class Complex {
private:
double _real;
double _imag;
public:
Complex();
Complex(double real, double imag);
Complex(const Complex& z);
Complex operator+(const Complex& u) const;
Complex operator+=(const Complex& u);
};
I already overloaded the + operator which works as expected:
Complex Complex::operator+(const Complex& u) const {
Complex z(_real + u._real, _imag + u._imag);
return z;
}
u=1-2i
v=2-1i
u+v=3-3i
In addition, I wanted to overload += as well:
Complex Complex::operator+=(const Complex& u) {
Complex z(_real + u._real, _imag + u._imag);
return z;
}
This however, does not work as expected and the result of u+=v is u=1-2i. Why is that the case?
Your compound assignment operator creates a new object z instead of changing the original object.
Declare the operator within the class definition like
Complex & operator+=(const Complex& u);
and define it the following way
Complex & Complex::operator+=(const Complex& u) {
_real += u._real;
_imag += u._imag;
return *this;
}
The operator can be defined as a non-class friend function. For example
class Complex {
private:
double _real;
double _imag;
public:
Complex();
Complex(double real, double imag);
Complex(const Complex& z);
Complex operator+(const Complex& u) const;
friend Complex & operator+=(Complex &v, const Complex& u);
};
Complex & operator+=(Complex &v, const Complex& u)
{
v._real += u._real;
v._imag += u._imag;
return v;
}
First of all assign like operators should return reference to assigned value.
Secondly your code should change value of current object.
There are couple solutions:
Complex& Complex::operator+=(const Complex& u) {
*this = Complex(_real + u._real, _imag + u._imag);
return *this;
}
Or
Complex& Complex::operator+=(const Complex& u) {
_real += u._real;
_imag += u._imag;
return *this;
}
I am stuck with regards to the 2 non-member, 2 non-friend multiplication and the addition of the operator overloading functions. I am unsure of how to do it. Could someone please assist in helping me to resolve this? Refer to my codes below. Thank you in advance!
Compiler output:
Point.cpp:208:19: error: passing ‘const CS170::Point’ as ‘this’ argument discards qualifiers [-fpermissive]
return other + value;
^~~~~
Point.cpp: In function ‘CS170::Point CS170::
operator*(double, const CS170::Point&)’:
Point.cpp:215:10: error: ‘double CS170::Point::x’ is private within this context
result.x = value * x;
^
Point.cpp:215:22: error: ‘x’ was not declared in this scope
result.x = value * x;
^
Point.cpp:216:10: error: ‘double CS170::Point::y’ is private within this context
result.y = value * y;
^
Point.cpp:216:23: error: ‘y’ was not declared in this scope
result.y = value * y;
Point.h
#include <iostream> // istream, ostream
namespace CS1100
{
class Point
{
public:
// Point(double X, double Y); // Constructors (2)
explicit Point(double x, double y);
Point();
Point operator+(const Point& other)const ;
Point& operator+(double value);
Point operator*(double value) ;
Point operator%(double value);
Point operator-(const Point& other)const ;
Point operator-(double value);
Point operator^(const Point& other);
Point operator+=(double value);
Point& operator+=(const Point& other) ;
Point& operator++();
Point operator++(int);
Point& operator--();
Point operator--(int);
Point& operator-();
// Overloaded operators (14 member functions)
friend std::ostream &operator<<( std::ostream &output, const Point &point );
friend std::istream &operator>>( std::istream &input, Point &point );
// Overloaded operators (2 friend functions)
private:
double x; // The x-coordinate of a Point
double y; // The y-coordinate of a Point
// Helper functions
double DegreesToRadians(double degrees) const;
double RadiansToDegrees(double radians) const;
};
// Point& Add(const Point& other); // Overloaded operators (2 non-member, non-friend functions)
// Point& Multiply(const Point& other);
Point operator+( double value, const Point& other );
Point operator-( double value, const Point& other );
My source code:
///////////////////////////////////////////////////////////////////////////////
// 2 non-members, non-friends (operators)
double operator+( double value, const Point& other )
{
return other + value;
}
double operator*( double value, const Point& other )
{
Point result;
result.x = value * x;
result.y = value * y;
return result;
}
As far as I understand the discussion to the question, the problem is not really the operators themselves, but the number of allowed member functions being limited – and you already have exceeded this limit.
However, you have quite a number of functions that don't need to be members, for instance:
class Point
{
public:
Point operator+(const Point& other) const
{
return Point(x + other.x, y + other.y);
}
};
Make free functions from all these:
class Point { /*...*/ };
Point operator+(Point const& l, Point const& r)
{
return Point(l.getX() + r.getX(), l.getY() + r.getY());
}
Having moved out all these operators like the one shown above, you get away far enough from the limit so that you can introduce the needed getters:
class Point
{
public:
double getX() { return x; };
double getY() { return y; };
};
If you are willing to rename the member variables, e. g. by adding a prefix, you can follow another pattern:
class Point
{
double m_x, m_y;
public:
double x() { return m_x; };
double y() { return m_y; };
void x(double v) { m_x = v; }; // the corresponding setter
// (for illustration, you might not need it)
};
This latter pattern is quite common, too. Advantage is being shorter for skipping the explicit get or set prefix, disadvantage is exactly losing this explicitness... Decide you, which one you prefer. More important than personal preference is consistency, though, so if there's e. g. a company's convention or common practice, follow that one...
Some of your operators will need to remain members, though, these are all those that modify the current object:
class Point
{
public:
Point& operator+=(const Point& other) /* const */ // NEEDS to be non-const
{
x += other.x;
y += other.y;
return *this; // <- very good hint to spot the ones needing to stay members
}
};
If you have a public copy constructor, you can re-use the operator+= for defining the operator+:
class Point
{
public:
Point(Point const& other) : Point(other.x, other.y) { }
};
Point operator+(Point const& x, Point const& y)
{
Point r(x); // or Point(x.x(), x.y()), if you lack such constructor)
r += y;
return r;
}
Actually, you can even spare the explicit copy by accepting one of the parameters by value:
Point operator+(Point x, Point const& y)
// ^ no reference
{
return x += y;
}
The latter rather for illustration, I'd prefer the two references in given case to keep the symmetry of the interface...
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();
Is it possible to create an overload for the ostream operator that does an arithmetic operation (addition for example) and then streams out the result? The standard ostream overload that can be found all over the web can only stream from a single variable. I need something that does the following:
std::cout << x+y << std::endl;
or even more complex expressions like:
std::cout << x*y+(3*z)^2 << std::endl;
where x, y, and z are instances of a simple custom-made struct where arithmetic operations are already defined (overloaded).
EDIT:
Here is my code:
struct scalar //complex scalar data structure
{
friend scalar operator^(const scalar&, int); //integer power operator overload
friend scalar exp(const scalar&); //exponential power function
std::ostream& operator<<(std::ostream&, const scalar&)
protected:
double re;
double im;
public:
double real() {return re;} //returns the real part
double imag() {return im;} //returns the imaginary part
scalar(double _re, double _im) {re=_re;im=_im;} //constructor 1
scalar(double _re) {re=_re;im=0.0;} //constructor 2
scalar(const scalar& s): re(s.re), im(s.im) {} //copy constructor
scalar& operator=(const scalar& rhs) //assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
re=rhs.re; //sets real parts equal
im=rhs.im; //sets imaginary parts equal
return *this;
}
scalar& operator+=(const scalar& rhs) //compound addition-assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
re=re+rhs.re; //adds real parts
im=im+rhs.im; //adds imaginary parts
return *this;
}
scalar& operator*=(const scalar& rhs) //compound multiplication-assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
double x1=re; double x2=rhs.re; double y1=im; double y2=rhs.im;
re=x1*x2-y1*y2; //multiplies real parts
im=x1*y2+x2*y1; //multiplies imaginary parts
return *this;
}
scalar& operator-=(const scalar& rhs) //compound subtraction-assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
re=re-rhs.re; //adds real parts
im=im-rhs.im; //adds imaginary parts
return *this;
}
scalar& operator/=(const scalar& rhs) //compound division-assignment operator overload
{
if (&rhs==this) return *this; //checks for self-assignment
double x1=re; double x2=rhs.re; double y1=im; double y2=rhs.im;
double n;
n =pow(x2,2)+pow(y2,2);
if (n==0) throw(1);
re=(x1*x2+y1*y2)/n; //multiplies real parts
im=(x2*y1-x1*y2)/n; //multiplies imaginary parts
return *this;
}
const scalar operator+(const scalar& b) //addition operator overload
{
scalar c = *this;
c+=b;
return c;
}
const scalar operator*(const scalar& b) //addition operator overload
{
scalar c = *this;
c*=b;
return c;
}
const scalar operator-(const scalar& b) //addition operator overload
{
scalar c = *this;
c-=b;
return c;
}
const scalar operator/(const scalar& b) //addition operator overload
{
scalar c = *this;
c/=b;
return c;
}
};
scalar i(0.0,1.0);
scalar j(0.0,1.0);
std::ostream& operator<<(std::ostream& out, const scalar& s)
{
out << s.re << '+' << s.im << 'i';
return out;
}
scalar operator^(scalar a, int b) //integer power operator overload
{
double x=a.real(); double y=a.imag();
if (x==0) throw(1);
int r=sqrt(pow(x,2)+pow(y,2));
int arg=atan2(y,x);
scalar c(r*cos(arg),r*sin(arg));
return c;
}
scalar exp(const scalar& s) //exponential power function
{
double x=s.re; double y=s.im;
scalar c(exp(x)*cos(y),exp(x)*sin(y));
return c;
}
Here is my main function:
int main()
{
scalar x(3,4);
scalar y=2;
cout << x*y << endl;
return 0;
}
This is is the output it is supposed to give:
6+8i
And this is the errors it gives instead:
In function 'std::ostream& operator<<(std::ostream&, const scalar&)':|
error: passing 'const scalar' as 'this' argument of 'double scalar::real()'
discards qualifiers|
And if I remove the const as the compiler says, I will get the following error:
error: no match for 'operator<<' in 'std::cout << scalar::operator*(const scalar&)
(((const scalar&)((const scalar*)(& y))))'|
The << operator can't handle the full expression - and why should it?
You need to implement the separate operators (operator+, operator*, ...) for your struct, which take your structs as parameters, do the corresponding operation on it, and return another of your structs. And only then define a operator<< taking a single one of your structs.
How would you even think of passing in such a complex structure to the operator<<, let alone parse it in there? Implement the separate operators, and leave the parsing to the compiler.
e.g. for a simple struct only encapsulating an int, doing that with + operation would look like this:
struct mystruct
{
int value;
};
then define:
mystruct const operator+(mystruct const & a, mystruct const & b)
{
mystruct result;
result.value = a.value + b.value;
return result;
}
and
std::ostream & operator<<(std::ostream& out, mystruct const & a)
{
out << a.value;
return out;
}
then you can do:
mystruct a, b;
a.value = 1;
b.value = 2;
std::cout << a+b;
Edit: With your updated code, there's exactly one problem:
std::ostream& operator<<(std::ostream&, const scalar&)
should be
friend std::ostream& operator<<(std::ostream&, const scalar&);
i.e. you're missing friend and an ;
Though the error you show suggests some different problem (which jrok's answer would have a solution for) - that doesn't seem to result from compiling the code you show! So please get the shown code and error message in sync.
The error is because functions scalar::real and scalar::imag are not const - you can only call const member functions when you've got a reference to a constant scalar.
double real() const {return re;}
double imag() const {return im;}
Why don't you just write std::cout << (x+y) << std::endl;
and be done?
As long as your overloaded operator takes its argument by value:
ostream& operator<<(ostream&, Thing)
or constant reference:
ostream& operator<<(ostream&, const Thing&)
you can use it for any expression with type Thing.
You should put parentheses around complex expressions, to avoid surprises from operator precedence; in particular, the second expression involving ^ won't be parsed as you expect.
You'll only be restricted to a single variable (or, more accurately, an lvalue expression) if the operator requires a non-constant reference; so don't do that.
UPDATE Now we've seen the code, the main issue is the in-class definition of operator<< as a member function; it can't be a member. Perhaps you want it to be a friend, so it can access im and re; or perhaps you should remove the declaration (making it a non-member, non-friend), and just use the public interface. If you do that, you'll need to add const to real() and imag(), so they can be called on a const object. You should do that anyway.
(Looking at the reported error, it seems you've already changed it to use the public interface, but haven't declared the necessary functions const).