C ++运算符重载错误 [英] Error with C++ operator overloading

查看:829
本文介绍了C ++运算符重载错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#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:

行62:错误:'const complex
complex :: operator +(const complex& $;
const complex&)'必须取
零或一个参数< br>
编译
由于-Wfatal错误而终止。

Line 62: error: 'const complex complex::operator+(const complex&, const complex&)' must take either zero or one argument
compilation terminated due to -Wfatal-errors.

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

推荐答案

有两个选项来重载二进制+运算符,作为自由函数或作为成员函数。作为成员函数,签名是类型运算符+(类型const&)const const 假设 a + b 不修改 a ,这似乎是一个公平的假设)。

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).

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

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;
}

这样,你不需要向自由功能授予友谊。在某些情况下,特别是使用模板时,有时候建议在类定义中定义运算符,在这种情况下,你必须使它成为 friend 但是由于语法原因:

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;
   }
};

使用此模式的原因...实现运算符+ = 首先,然后运算符+ 在它的顶部提供两个单独的操作少的额外成本(实现它作为成员函数( operator + = 也可以是一个自由函数)使它类似于 operator = (必须是会员),避免需要友谊。

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.

c> operator + 作为自由函数与操作的类型对称性相关。添加是可交换的( a + b == b + a ), 。你提供了一个隐式构造函数(你的复杂类型可以隐式转换从一个int由于构造函数 complex(double r = 0,double i = 0)

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.

如果运算符+ 实现为一个成员函数,编译器只允许在第一个参数是 complex 时考虑重载,并且将隐式转换另一个参数,允许您键入<$ c $问题是如果你颠倒顺序 5 + complex(0,0),编译器不能将 5 转换为复合体,然后使用成员 operator + 。另一方面,自由函数,编译器将检测两个参数中的一个匹配,并尝试并成功转换另一个参数。最终结果是通过使用一个自由函数,允许一个实现所有这三个添加: complex + complex complex + double (以及所有积分和浮点类型,因为它们可以转换为 double

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 5to 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

$ c> operator + 以值的第一个参数表示编译器在某些情况下可以复制一个副本: a + b + c code>(a + b)+ c ,第一个操作的临时结果可以直接用作第二个调用的参数,无需额外复制。

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.

这篇关于C ++运算符重载错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆