在C ++中使用const替换两个参数的运算符

时间:2009-01-04 12:34:33

标签: c++ operator-overloading override overloading

我正在尝试使用两个const参数创建一个重写的运算符函数,但我无法弄清楚如何执行它。这是一个简单的例子:

class Number
{
    Number()
    {
        value = 1;
    };

    inline Number operator + (const Number& n)
    {
        Number result;

        result.value = value + n.value;
        return result;
    }

    int value;
}

我在这里要做的是将两个参数传递给另外的函数,它们都是const并返回结果而不改变类中的任何内容:

const Number a = Number();
const Number b = Number();
Number c = a + b;

这可能吗?我将如何做到这一点?

谢谢,

4 个答案:

答案 0 :(得分:7)

inline在类声明中被理解,因此您无需指定它。

大多数惯用语,你会使operator+在类定义之外声明的非成员函数,如下所示:

Number operator+( const Number& left, const Number& right );

如果需要访问friend的内部,您可能需要将其设为Number

如果你必须将它作为一个成员函数,那么你需要使函数本身为const:

Number operator+( const Number& n ) const
{ // ...

对于像Number这样的类,operator+通常以operator+=的形式实现,因为通常您希望所有常用运算符按预期工作,operator+=通常更容易实施和operator+往往不会因为单独实施而失去任何效率。

课堂内:

Number& operator+=( const Number& n );

课外:

Number operator+( const Number& left, const Number& right )
{
    return Number( left ) += right;
}

甚至:

Number operator+( Number left, const Number& right )
{
    return left += right;
}

答案 1 :(得分:1)

class Number
{
    Number()
    {
        value = 1;
    };

    inline Number operator + (const Number& n) const
    {
        Number result;

        result = value + n.value;
        return result;
    }

    int value;
}

答案 2 :(得分:1)

怎么样:

inline Number operator + (const Number& n) const

答案 3 :(得分:1)

虽然我觉得以前的答案已经足够好了,但我相信还需要做一些澄清。

运营商(通常)有两种风格

第一个是非成员函数,第二个是成员函数,其参数是操作的“右操作数”,通常返回当前修改后的对象。

例如,假设某个类§有一个运算符T。它可以写成非成员函数

T operator § (const T & lhs, const T & rhs)
{
   T result ;
   // do the lhs § rhs operation, and puts the result into "result"
   return result ;
}

或作为成员函数

T & T::operator § (const T & rhs)
{
   // do the "this § rhs" operation, and puts the result into "this"
   return *this ;
}

或甚至(非常不寻常)作为另一个成员函数

T T::operator § (const T & rhs) const
{
   T result ;
   // do the "this § rhs" operation, and puts the result into "result"
   return result ;
}

通常,您应该更喜欢非成员函数,只是因为您不应该声明它是朋友。因此,使用非成员非友元函数可以增强对象的封装。

免责声明:还有其他风格,但我将自己局限于+*/-等算术运算符。 ,以及“可靠的”运营商原型。

分析您对运营商的使用

如果是+

  1. 每个操作数必须保持不变,因为a = b + c不能更改b,也不能更改c
  2. 您可以像+一样积累a = b + c + d + e,因此临时工具必须存在。
  3. T operator § (const T & lhs, const T & rhs)
    {
       T result ;
       // do the lhs § rhs operation, and puts the result into "result"
       return result ;
    }
    

    如果是+=

    1. 您知道左操作数A(来自A + = B)将被修改。
    2. 你知道左操作数A(来自A + = B)是它自己的结果。
    3. 所以你应该使用:

      T & T::operator += (const T & rhs)
      {
         // do the "this § rhs" operation, and puts the result into "this"
         return *this ;
      }
      

      与往常一样,过早优化是万恶之源

      我在生产代码中看到过这种代码,所以确实发生了:

      T & operator + (const T & lhs, const T & rhs)
      {
         static T result ; // result is STATIC !!!!
         // do the lhs + rhs operation, and puts the result into "result"
         return result ;
      }
      

      作者希望节约一个暂时的。使用这种代码,编写a = b + c + d会导致有趣(和错误)的结果。

      ^ _ ^

      最后但并非最不重要

      我确实在this page上写了一个运算符重载原型列表。该页面仍在构建中,但其主要用途(易于复制/粘贴工作原型)非常有用......