0

我正在尝试使用两个 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

4 回答 4

7

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

最惯用的做法operator+是,在类定义之外声明一个非成员函数,如下所示:

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

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

如果必须将其作为成员函数,则需要使函数本身为 const:

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

对于像 , 这样的类Numberoperator+通常按照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;
}
于 2009-01-04T12:40:10.610 回答
1
class Number
{
    Number()
    {
        value = 1;
    };

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

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

    int value;
}
于 2009-01-04T12:37:24.390 回答
1

怎么样:

inline Number operator + (const Number& n) const
于 2009-01-04T12:38:27.337 回答
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. +您可以像 in 一样累积,a = b + c + d + e因此必须存在临时对象。
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)是它自己的结果。

所以你应该使用:

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会导致有趣(和错误)的结果。

^_^

最后但并非最不重要的

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

于 2009-01-04T13:30:10.493 回答