Complex operator*(double m, const
Complex & c)
{ return c * m; }
*On the code above, i'm trying to multiply a constant to a complex number. i receive some errors one of them is [ binary 'operator ' has too many parameters]
ostream & operator<<(ostream & os,
Complex & c)
{os << c.real <<"," << c.imaginary; return os;}
*****Can you tell me what i did wrong on this line as well.
Thanks*****
#include <iostream>
using namespace std;
class Complex
{
private:
double real;
double imaginary;
public:
Complex();
Complex(double r, double i = 0);
Complex operator*(const Complex & c) const;
Complex operator*(double mult) const;
Complex operator*(double m, const Complex & c)
{ return c * m; }
ostream & operator<<(ostream & os, Complex & c)
{os << c.real <<"," << c.imaginary; return os;}
};
Complex::Complex()
{
real = imaginary = 0;
}
Complex::Complex(double r, double i )
{
real = r;
imaginary = i;
}
Complex Complex::operator*(const Complex & c) const
{
Complex mult;
mult.imaginary = imaginary * c.imaginary;
mult.real = real * c.real;
return mult;
}
Complex Complex::operator*(double mult) const
{
Complex result;
result.real = real * mult;
result.imaginary = imaginary * mult;
return result;
}
int main()
{
Complex B(5, 40);
Complex C(6, 15);
cout << "B, and C:\n";
cout << B << ": " << C << endl;
cout << "B * C: " << B*C << endl;
cout << "10 * B: " << 10*B << endl;
return 0;
}
These two operators have problems:
class Complex {
// ...
Complex operator*(double m, const Complex & c)
{return c * m;}
ostream & operator<<(ostream & os, Complex & c)
{os << c.real <<"," << c.imaginary; return os;}
// ...
};
Before anything else: That operator<< isn't supposed to change the complex outputs, so that should be const. (Otherwise you cannot output temporary objects, as they can't be bound to non-const references.)
Since they are non-static member functions, they have an implicit this parameter. With that, they have three parameters. However, both are binary operators. Since you cannot make them static (that's just because the rules say so), you have to implement them as free functions. However, as they are implemented, they need access to private members, so you would have to make them friends of your class:
class Complex {
// ...
friend Complex operator*(double m, const Complex & c);
friend ostream & operator<<(ostream & os, const Complex & c);
// ...
};
Complex operator*(double m, const Complex & c)
{return c * m;}
ostream & operator<<(ostream & os, const Complex & c)
{os << c.real <<"," << c.imaginary; return os;}
On a sidenote, it's possible to implement them inline at the point of the friend declaration, which brings you back almost to your original version:
// note the friend
class Complex {
// ...
friend Complex operator*(double m, const Complex & c)
{return c * m;}
friend ostream & operator<<(ostream & os, const Complex & c)
{os << c.real <<"," << c.imaginary; return os;}
// ...
};
However, if you implement a concrete mathematical type, your type's users will expect all operations common for such types to work with it. That is, they will, for example, expect c*=r to simply work. So you will need to overload operator*=, too. But that operator does almost the same as operator*, so it would be a good idea to implement one on top of the other. A common idiom is to implement *= (and += etc.) as member functions (since they change their left argument, it's a good idea for them to have access to its private data) and operator* as non-member on top of that. (Usually that's more efficient then the other way around.):
// note the friend
class Complex {
// ...
Complex& operator*=(double rhs)
{return /* whatever */;}
friend ostream & operator<<(ostream & os, const Complex & c)
{os << c.real <<"," << c.imaginary; return os;}
// ...
};
inline Complex operator*(Complex lhs, double rhs) // note: lhs passed per copy
{return lhs*=rhs;}
inline Complex operator*(double lhs, const Complex& rhs)
{return rhs*lhs;}
IMO that's the best solution.
I have. however, a few more things to say:
The way you implemented your multiplication is inefficient:
Complex Complex::operator*(const Complex & c) const
{
Complex mult;
mult.imaginary = imaginary * c.imaginary;
mult.real = real * c.real;
return mult;
}
When you say Complex mult;, you invoke the default constructor of your class, which initializes the real and imaginary parts to 0. The next thing you do is to overwrite that value. Why not do it in one step:
Complex Complex::operator*(const Complex & c) const
{
Complex mult(real * c.real, imaginary * c.imaginary);
return mult;
}
or even to more concise
Complex Complex::operator*(const Complex & c) const
{
return Complex(real * c.real, imaginary * c.imaginary);
}
Sure, it's just two assignments per multiplication. But then - you wouldn't want to have this in some inner loop of your graphic driver.
Also, your constructors are not implemented The Way It Ought To be(TM). For initializing member data, you should use the initializer list:
Complex::Complex()
: real(), imaginary()
{
}
Complex::Complex(double r, double i)
: real(r), imaginary(i)
{
}
While it doesn't make any difference for built-in types like double, it doesn't hurt either and it's good to not to get into the habit. With user-defined types (a somewhat unfortunate name, since it is for all non-built-ins, even types like std::string, which isn't defined by users) that have a non-trivial default constructor, it does make a difference: it's far less efficient.
The reason is that, when the execution passes that initial {, C++ guarantees that your data member objects are accessible and usable. For that, they must be constructed, because construction is what turns raw memory into objects. So even if you do not call a constructor explicitly, the run-time system will still call the default constructors. If the next thing you do is overriding the default-constructed values, you're again wasting CPU cycles.
Finally, this constructor Complex(double r, double i = 0) serves as an implicit conversion operator. That is, if, for example, youe meant to call f(real), but forgot to include it, but there is an f(const complex&) in scope, the compiler exercises its right to perform one user-defined conversion and your call f(4.2) becomes f(Complex(4.2)) and the wrong function is silently called. That's very dangerous.
In order to avoid this, you should mark all constructors explicit that could be called with only one argument:
class Complex {
// ...
explicit Complex(double r, double i = 0)
// ...
};
Don't declare Complex operator*(double m, const Complex & c) and the ostream one as member functions (aka methods): declare them as friend functions instead! (If you even need them to be friends, which you wouldn't if you had the obvious inline accessor methods for the imaginary and real parts -- but anyway the point is that they have to be outside the class!).
For member functions, operator* and operator<< only take a single parameter, as the Complex object is already implicitly given, i.e.
c * r
translates to
c.operator*(r)
If you wish to have the two argument form, then an external friend function is what you are looking for. Although, as Alex points out, if you have re and im acessors set up, then your external operators need not be friends.
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();
I need your help, please have a look at the following code I get error
as following:
no match for operator *(operand types are'doubles and 'lists')
this is inherited class, header file(before operator* function it worked properly)
class lists:public vectorebi
{
public:
lists (double first_);
lists (double first_, lists var_);
double operator-(const double& answer);
lists operator*(const lists &answer) const;
virtual ~lists(){};
private:
friend std::ostream& operator<<(std::ostream& os, lists& arg);
double first;
lists* var;
};
//soucre file
lists::lists(double first_){
first=first_;
}
lists::lists(double first_, lists var_){
first=first_;
var=&var_;
}
double lists::operator-(const double& answer){
double result = answer - first;
return result;
}
lists lists::operator*(const lists &answer) const
{
lists k = first * answer.first;
return k;
}
std::ostream& operator<<(std::ostream& os, lists& arg) {
os << "(" << arg.var << ")";
return os;
}
and the main ///
int main()
{
double answer1 = 15;
lists k=5;
lists answer = k * answer1; //here is an error as compiler points
cout << answer;
return 0;
}
I will appreciate your help, I am trying to multiply variable of type my class and double, is it possible?
* is a binary operator, meaning it expects 2 arguments.
When you say a * b, a becomes the first (left) argument and b becomes the second (right) argument. Effectively the function call looks like a.operator*(b).
You are doing, answer1 * k which evaluates to the call answer1.operator*(k) . This means double must have operator* overloaded for lists.
But you want it for your class lists. So you must do this in main():
lists answer = k * answer1;
And operator* must be declared as:
lists lists::operator*(const double& answer)
{
lists k = first * answer; // not sure how double * double equals lists
return k;
}
EDIT:
Regarding the error
lists* lists::var is private within this context
which you pointed out in the comments, it appears because of the inconsistent declaration of friend operator<<.
You have declared it as:
friend std::ostream& operator<<(std::ostream& os, const lists& arg); // note the `const` for `arg`
But you have defined it as:
std::ostream& operator<<(std::ostream& os, lists& arg) // `const` missing!!
{
....
}
Just add const in the definition as well, and it will work as expected.
The line:
lists answer = answer1 * k;
fails because the compiler is looking for a * overload on a double that takes lists instance. This method doesn't exist, but you can define it my creating the method outside your class:
lists operator*(double lhs, const lists &rhs)
{
return lists(lhs) * rhs;
}
NOTE: I've made rhs a const as this is best practice for operator overloads like this which do not (and should not) modify their inputs:
lists operator*(const lists &answer) const;
in the declaration and:
lists lists::operator*(const lists &answer) const
{
lists k = first * answer.first;
return k;
}
in the implementation.
NOTE: I think you meant to multiple by answer.first and otherwise the code doesn't make much sense.
Also, your streaming operator currently tries to output var which is a member variable you never initialize. I suspect you want to output first so change it to this:
std::ostream& operator<<(std::ostream& os, const lists& arg)
{
os << "(" << arg.first << ")";
return os;
}
I've made arg const as this is the recommended practice. You'll need to update your class definition to reflect this.
I've been making a class called Complex for storing and working with complex numbers. I'm having issues where my overloaded + and * functions return an obscenely large number, which I can only presume has something to do with pointers, but I'm very new to using them. I've copied the output here:
c1: 1 - i5
c2: -4 + i3
c1 + c2: -9.25596e+061 - i9.255
c1 * c2: -9.25596e+061 - i9.255
Press any key to continue . . .
Here is the class architecture:
// Complex.h
#include <iostream>
#include <cmath>
using namespace std;
class Complex
{
friend std::ostream &operator<<(std::ostream &, const Complex &);
friend std::istream &operator>>(std::istream &, Complex &);
friend Complex &operator+(const Complex &, const Complex &);
friend Complex &operator+(const Complex &, const double &);
friend Complex &operator+(const double &, const Complex &);
friend Complex &operator*(const Complex &, const Complex &);
friend Complex &operator*(const Complex &, const double &);
friend Complex &operator*(const double &, const Complex &);
public:
explicit Complex(double re=0, double im=0);
void setReal(double re);
void setImag(double im);
double &getReal();
double &getImag();
~Complex();
private:
double real;
double imag;
};
And here I have the relevant portions of my program:
// Complex.cpp
#include "Complex.h"
ostream &operator<<(ostream &output, const Complex &num)
{
output << num.real << (num.imag >= 0 ? " + i" : " - i") << abs(num.imag);
return output;
}
Complex &operator+(const Complex &num1, const Complex &num2)
{
Complex sum(num1.real + num2.real, num1.imag + num2.imag); // Create new complex by summing elements
return sum;
}
Complex &operator*(const Complex &num1, const Complex &num2)
{
Complex prod(num1.real * num2.real - num1.imag * num2.imag, num1.real * num2.imag + num1.imag * num2.real); // Create new complex by expansion
return prod;
}
Complex::Complex(double re, double im)
{
real = re;
imag = im;
}
int main() {
Complex c1(1.0, -5.0);
Complex c2(-4.0, 3.0);
cout << "c1: " << c1 << endl;
cout << "c2: " << c2 << endl;
cout << "c1 + c2: " << c1 + c2 << endl;
cout << "c1 * c2: " << c1 * c2 << endl;
system("pause");
}
I feel bad bothering you guys about this. Do you possibly know of a site that does a good job of explaining concepts for C++ like pointers, least-privilege, polymorphism, inheritance, etc?
Sorry for asking basic questions on here, but it's hard to find resources that explain this stuff clearly.
Wrong return type:
Complex &operator+(const Complex &num1, const Complex &num2)
^^^^^^^^^
You're creating a temporary Complex and returning it by reference, and then it gets destroyed so you have a dangling reference. Since operator+ is constructing a new object and returning it, it should return it by value... so the signature should be:
Complex operator+(Complex const&, Complex const& );
The problem is that most of your overloaded operators return a reference to a local var, which is destroyed when the operator function returns, leaving you with a dangling reference. Try changing your operators to return a Complex rather than a Complex &:
Complex operator+(const Complex &num1, const Complex &num2)
{
Complex sum(num1.real + num2.real, num1.imag + num2.imag); // Create new complex by summing elements
return sum;
}
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 have a class "complex" that contains a Real and an Imaginary value. I'm trying to overload the + operator so I can add real to real and imaginary to imaginary, but I'm banging my head against a wall here.
In the function, I can get the values easy. Returning them however, is a bitch.
My plan is to overload the '=' operator, too, so I can go
complex a, b, c;
(set a and b)
c = a + b;
then have a+b return a complex, then have complex c equal the complex returned by a+b
Any opinion on whether that's a viable path?
Any opinion on whether it can be done easier?
Return them as a complex! e.g.
const complex operator+(const complex &a, const complex &b)
{
return complex(a.re + b.re, a.im + b.im);
}
You shouldn't need to overload operator=; the compiler will generate one for you that does an element-by-element copy, which will probably suffice for a complex class.
I'm not sure I understand the problem. Do you have a complex class?
struct complex
{
complex(float real, float imag) :
real(real), imag(imag)
{}
// first make the mutating version
complex& operator+=(const complex& rhs)
{
real += rhs.real;
imag += rhs.imag;
return *this;
}
float real, imag;
};
// then use that for the non-mutating version
complex operator+(complex lhs, const complex& rhs)
{
lhs += rhs;
return lhs;
}
This is, of course, just an exercise; we have std::complex.
What's wrong with overloading the + operator:
complex operator+(const complex& a, const complex& b) const {
return complex(a.real + b.real, a.imag + b.imag);
}
And the operator=() similarly? (but the compiler give you this by default)
complex& operator=(const complex& a) {
real = a.real;
imag = a.imag;
return *this;
}
It is viable but there is already complex class in standard library. Reuse it or at least have a look how the operator overloading is done there.