关于重载运算符+的问题

时间:2010-03-07 08:18:18

标签: c++ operator-overloading

请考虑以下代码:


class A
{
public:
    A& operator=( const A& );
    const A& operator+( const A& );
    const A& operator+( int m );
};

int main()
{
    A a;
    a = ( a + a ) + 5;   // error: binary '+' : no operator found which takes a left-hand operand of type 'const A'
}

任何人都可以解释为什么将上述内容作为错误返回?

( a + a )”调用“const A& operator+( const A& )”并返回一个常量引用,如果我没记错,则会将其传递给“const A& operator+( int m )”。

如何修复上述错误(不创建全局二元运算符+或接受int的构造函数),以便允许main()内的语句?

6 个答案:

答案 0 :(得分:7)

  

然后传递给“const A& operator +(int m)”如果我没弄错的话

没有。由于LHS是const A&而RHS是int,因此会调用*

[anyType] operator+ (int rhs) const
//                            ^^^^^ note the const here.

由于您只提供了非const版本const A& operator+( int m ),编译器会抱怨。

*:或operator+(const int& rhs) constoperator+(float rhs) const ......关键点在于它必须是const方法。

答案 1 :(得分:6)

operator+应该返回一个实例,而不是引用:

// as member function
A operator+(const A& other);

// as free function
A operator+(const A& left, const A& right);

解释具体问题是“返回一个常量引用,然后传递给const A& operator+( int m )”。由于你有一个const引用,它不能调用该函数,因为它不是const方法(即const A& operator+( int m ) const)。

那就是说,这不是修复operator+的方法。如果你要返回一个引用,它的引用是什么?运算符+中的本地会很糟糕,因为您不应该返回对本地的引用。对全局的引用会很糟糕,因为它会限制代码的正确使用方式。对分配的内存的引用会很糟糕,因为它会泄漏内存。对*this的引用会很糟糕,因为operator+的行为与operator +=相似。

答案 2 :(得分:2)

因为您在添加时正在修改左侧对象。你不能用const对象做到这一点。以Samuel建议为例,因为惯用的方法是返回添加对象的新副本。

答案 3 :(得分:1)

问题是(a+a)会返回一个所谓的 rvalue (基本上是一个临时的花哨术语)。虽然可以在rvalue上调用成员函数,但只能调用const成员函数。此外,每个人都说operator+必须返回一个新值。

您的运营商应该像这样实施:

A operator+( const A& ) const;
A operator+( int m ) const;

但是,不修改左参数的二元运算符可能更好地实现为自由函数:

class A { ... };

A operator+(const A& lhs, const A& rhs);
A operator+(const A& lhs, int rhs);

通常,它们是在operator+=之上实现的,它是作为成员实现的:

class A {
  public:
   A& operator+=(const A& rhs);
   A& operator+=(int rhs);
};

inline A operator+(A lhs, const A& rhs) // note: lhs is passed by copy now
{
  lhs += rhs;
  return lhs;
}
A operator+(A lhs, int rhs) // note: lhs is passed by copy now
{
  lhs += rhs;
  return lhs;
}

答案 4 :(得分:1)

该函数需要为const:

const A& operator+( int m ) const;

答案 5 :(得分:1)

const A& operator+( const A& )返回一个const引用时,不能通过const对象调用非const成员函数const A& operator+( int m )。  或者,第一个运算符应定义为A& operator+( const A& ),或第二个运算符定义为const A& operator+( int m )const;  但是,这些更改只会使它们在技术上正确,在大多数情况下不会在美学上,因为二元运算符不应该修改任何输入参数,而是计算结果并返回。因此,结果必须通过值返回,或者在C ++ 0x的情况下,作为r值引用。 即A operator+(const A& rhs)constA&& operator+(const A& rhs)const;