问题
#include<iostream>
using namespace std;
class complex {
double real;
double image;
public:
complex(double r=0,double i=0) : real(r), image(i) { };
complex(const complex& c) : real(c.real), image(c.image) { };
~complex(){};
double re() const {
return real;
};
double im() const{
return image;
};
const complex& operator =(const complex&c)
{
real = c.real;
image = c.image;
return *this;
};
const complex& operator +=(const complex&c)
{
real += c.real;
image += c.image;
return *this;
};
const complex& operator -=(const complex&c)
{
real -= c.real;
image -= c.image;
return *this;
};
const complex& operator *=(const complex&c)
{
double keepreal=real;
real = real * c.real - image * c.image;
image = keepreal * c.image + image * c.real;
return *this;
};
const complex& operator /=(double d)
{
real/=d;
image/=d;
return *this;
};
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());
};
const complex& operator /=(const complex&c)
{
return *this *= (!c) /= abs2(c);
};
const complex operator +(const complex& c, const complex& d)
{
return complex(c.re() + d.re(), c.im() + d.im());
};
const complex operator -(const complex& c, const complex& d)
{
return complex(c.re() - d.re(), c.im() - d.im());
};
const complex operator -(const complex&c)
{
return complex(-c.re(), -c.im());
};
const complex operator /(const complex& c,const complex& d)
{
return complex(c) /= d;
};
};
int main() {
complex c = 1., d(3.,4.);
return 0;
}
OUTPUT:
Line 62: error: 'const complex complex::operator+(const complex&, const complex&)' must take either zero or one argument
compilation terminated due to -Wfatal-errors.
please help: http://codepad.org/cOOMmqw1
回答1:
There are two alternatives to overload the binary + operator, as a free function or as a member function. As a member function the signature is Type operator+( Type const & ) const
(const
is optional there, but I am assuming that a+b
does not modify a
, which seems a fair assumption).
The alternative approach is using a free function that takes two objects and returns the sum. There are different signatures for this, but the most widely accepted would be: Type operator+( Type lhs, Type const & rhs )
(note that the first argument is by value), where the implementation internally modifies and returns lhs
. In particular a common approach to arithmetic operator overloading is implementing operator+=
as a member function, and then implementing a free function operator+
in terms of the former:
struct Type {
// ...
Type& operator+=( Type const & );
};
Type operator+( Type lhs, Type const & rhs ) {
return lhs+=rhs;
}
This way, you don't need to grant friendship to the free function. In some cases, in particular with templates, it is sometimes recommended to define the operator inside the class definition, and in that case you will have to make it a friend
(not for access, but for syntactic reasons:
struct Type {
// ...
Type& operator+=( Type const & );
// Still a free function:
friend Type operator+( Type lhs, Type const & rhs ) {
return lhs+=rhs;
}
};
As of the reasons to use this pattern... Implementing operator+=
first and then operator+
on top of it provides the two separate operations for little extra cost (operator+
is a one-liner function!). Implementing it as a member function (operator+=
could also be a free function) makes it similar to operator=
(must be member) and avoids the need for friendship.
The reason for implementing operator+
as a free function are related to type symmetry of the operation. Addition is commutative (a+b
== b+a
), and you would expect the same while using your type. You have provided an implicit constructor (your complex type can be implicitly converted from an int due to the constructor complex( double r = 0, double i = 0 )
, and that allows the compiler to use those conversions if a function call does not perfectly match an overload.
If operator+
is implemented as a member function, the compiler is only allowed to consider that overload when the first argument is a complex
, and will implicitly convert the other argument, allowing you to type complex(0,0)+5
. The problem is that if you reverse the order 5+complex(0,0)
the compiler cannot convert 5
to a complex and then use the member operator+
. On the other hand, if you provide it as a free function, the compiler will detect that one of the two arguments matches in both cases, and will try and succeeds converting the other argument. The net result is that by using a free function you are allowing with a single implementation all these three additions: complex+complex
, complex+double
, double+complex
(and additionally for all integral and floating point types, since they can be converted to double
Having operator+
take the first argument by value means that the compiler can under some circumstances elide a copy: a + b + c
binds as (a+b) + c
, the temporary result of the first operation can be used directly as argument to the second call, without extra copying.
回答2:
You overload the +,/,-, and * like this
complex operator+(const complex& c) const
You only need one argument since the left hand argument is this
Example
complex operator+(const complex& c) const
{
return complex(c.re()+this->re(),c.im()+this->im());
};
回答3:
The + operator should take one parameter:
complex operator+(const complex& c) const
{
return complex(c.re()+re(),c.im()+im());
}
The other complex is the current object.
回答4:
Your
const complex operator+(const complex& c, const complex& d)
{
return complex(c.re()+d.re(),c.im()+d.im());
};
is a member function of complex
. That prototype is for a global operator+
. In a member function c
is assumed to be *this
, so is not specified.
But you really need to start formatting your code properly, starting with indenting. Beginning programmers don't realize how important proper formatting is when showing your code to others.
回答5:
There is also another way to overload binary operator, if you are really looking for two parameters operator overloading. Then you can try something like this.
friend complex operator+(const complex& c, const complex& d)
{
complex r;
r.real = c.re() + d.re();
r.image = c.im() + d.im();
return r;
}
来源:https://stackoverflow.com/questions/6067535/error-with-c-operator-overloading