C++运算符重载错误

gma*_*man 0 c++ overloading operator-keyword

#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;
}
Run Code Online (Sandbox Code Playgroud)

OUTPUT:

第62行:错误:'const complex complex :: operator +(const complex&,const complex&)'必须
由于-Wfatal-errors而使零或一个参数编译终止.

请帮忙:http://codepad.org/cOOMmqw1

Dav*_*eas 10

重载二元+运算符有两种选择,作为自由函数或成员函数.作为成员函数,签名是Type operator+( Type const & ) const(const在那里是可选的,但我假设a+b不会修改a,这似乎是一个公平的假设).

另一种方法是使用一个自由函数,它接受两个对象并返回总和.对此有不同的签名,但最广泛接受的是:( Type operator+( Type lhs, Type const & rhs )注意第一个参数是按值),其中实现在内部修改并返回lhs.特别是算术运算符重载的一种常见方法是operator+=作为成员函数实现,然后operator+根据前者实现自由函数:

struct Type {
   // ...
   Type& operator+=( Type const & );
};
Type operator+( Type lhs, Type const & rhs ) {
   return lhs+=rhs;
}
Run Code Online (Sandbox Code Playgroud)

这样,您就不需要为自由函数授予友谊.在某些情况下,尤其是模板,有时建议在类定义中定义运算符,在这种情况下,您必须将其设置为friend(不是为了访问,而是出于语法原因:

struct Type {
   // ...
   Type& operator+=( Type const & );
   // Still a free function:
   friend Type operator+( Type lhs, Type const & rhs ) {
      return lhs+=rhs;
   }
};
Run Code Online (Sandbox Code Playgroud)

由于使用这种模式的原因... operator+=首先实现然后operator+在它上面提供两个单独的操作,只需很少的额外成本(operator+是一个单行功能!).将其实现为成员函数(operator+=也可以是自由函数)使其类似于operator=(必须是成员)并避免需要友谊.

operator+作为自由函数实现的原因与操作的类型对称性有关.添加是可交换的(a+b== b+a),并且在使用您的类型时您会期望相同.您提供了一个隐式构造函数(由于构造函数complex( double r = 0, double i = 0 ),您的复杂类型可以从int隐式转换,并且如果函数调用与过载完全匹配,则允许编译器使用这些转换.

如果operator+作为成员函数实现,则只允许编译器在第一个参数为a时考虑该重载complex,并且将隐式转换另一个参数,允许您键入complex(0,0)+5.问题是,如果您颠倒顺序5+complex(0,0),编译器无法转换5为复合体,然后使用该成员operator+.另一方面,如果您将其作为自由函数提供,编译器将检测两个参数中的一个在两种情况下都匹配,并将尝试成功转换另一个参数.最终的结果是,通过使用免费的功能,你让一个单一的实现这三个加法:complex+complex,complex+double,double+complex(和另外所有整数和浮点类型,因为它们可以被转换成double

operator+按值取第一个参数是指在某些情况下,编译器的Elid可以复制:a + b + c结合为(a+b) + c,第一操作的临时结果可以直接作为参数传递给第二个电话,而无需额外的拷贝.


Pep*_*epe 5

你像这样重载+,/, - 和*

complex operator+(const complex& c) const 
Run Code Online (Sandbox Code Playgroud)

你只需要一个参数,因为左手参数是 this

complex operator+(const complex& c) const 
{
    return complex(c.re()+this->re(),c.im()+this->im());
};
Run Code Online (Sandbox Code Playgroud)