Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+;中,对两个参数使用const重写运算符+;_C++_Operator Overloading_Overriding_Overloading - Fatal编程技术网

C++ 在C+;中,对两个参数使用const重写运算符+;

C++ 在C+;中,对两个参数使用const重写运算符+;,c++,operator-overloading,overriding,overloading,C++,Operator Overloading,Overriding,Overloading,我正在尝试使用两个常量参数创建一个重写的运算符函数,但我不知道如何实现它。下面是一个简单的例子: class Number { Number() { value = 1; }; inline Number operator + (const Number& n) { Number result; result.value = value + n.value; return resu

我正在尝试使用两个常量参数创建一个重写的运算符函数,但我不知道如何实现它。下面是一个简单的例子:

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

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

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

    int value;
}
我在这里要做的是将两个参数传入加法函数,它们都是常量并返回结果,而不更改类中的任何内容:

const Number a = Number();
const Number b = Number();
Number c = a + b;
Number& operator+=( const Number& n );
Number operator+( const Number& left, const Number& right )
{
    return Number( left ) += right;
}
这可能吗?我将如何着手做这件事

谢谢

怎么样:

inline Number operator + (const Number& n) const

inline
在类声明中是可以理解的,所以您不需要指定它

最惯用的方法是,将
运算符+
作为类定义之外声明的非成员函数,如下所示:

Number operator+( const Number& left, const Number& right );
如果类需要访问
Number
的内部结构,您可能需要将其设置为类的
朋友

如果必须将其作为成员函数,则需要将函数本身设置为常量:

Number operator+( const Number& n ) const
{ // ...
对于像
Number
这样的类,
operator+
通常是按照
operator+=
实现的,因为通常您希望所有常用的操作符都能按预期工作,
operator+=
通常更容易实现,
operator+
在单独实现时不会失去任何效率

课堂内:

const Number a = Number();
const Number b = Number();
Number c = a + b;
Number& operator+=( const Number& n );
Number operator+( const Number& left, const Number& right )
{
    return Number( left ) += right;
}
课外活动:

const Number a = Number();
const Number b = Number();
Number c = a + b;
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;
}

虽然我觉得前面的答案已经足够好了,但我认为需要澄清一下

操作员(通常)有两种风格 第一个是非成员函数,第二个是成员函数,其参数是操作的“右操作数”,通常返回当前修改的对象

例如,假设一个类
T
有一个操作符
§
。它可以写为非成员函数:

或作为成员函数:

甚至(非常罕见)作为另一个成员函数:

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

免责声明:还有其他风格,但我仅限于算术运算符,如
+
*
/
-
,等等,以及“可靠”的运算符原型

分析你对操作符的使用 在
+
的情况下:

  • 每个操作数都需要是常量,因为
    a=b+c
    不能更改
    b
    ,也不能更改
    c
  • 您可以累积
    +
    ,如
    a=b+c+d+e
    ,因此临时表必须存在
  • +=
    的情况下:

  • 您知道左操作数A(从A+=B)将被修改
  • 您知道左操作数A(来自A+=B)是它自己的结果
  • 因此,您应该使用:

    T & T::operator += (const T & rhs)
    {
       // do the "this § rhs" operation, and puts the result into "this"
       return *this ;
    }
    
    一如既往,过早优化是万恶之源 我在生产代码中见过这种代码,所以确实发生了:

    作者希望节约一点时间。使用这种代码,编写
    a=b+c+d
    会产生有趣(错误)的结果

    ^_^

    最后不能不提
    我确实在上面写了一个操作符重载原型列表。该页面仍在构建中,但其主要用途(易于复制/粘贴工作原型)可能非常有用…

    可能吗?result.value=值+n.value;您是对的(正在动态编辑)-更改。您不应该在operator+的实现中复制“left”并修改副本吗?我不确定这是否很重要。若Number有一个私有副本构造函数或者可以抛出(在这种情况下,operator+可以捕获它),那个么它就可以抛出。它还可以从派生类中进行切片(因此,我们将失去可能需要的任何多态性)。但我认为情况并非如此。对不起,我只是误读了代码:他当然是在复制传递值中的“left”。出于某种原因,我把它读作数字&左。但如果可以的话,我会假装我是因为多态性的原因而抱怨,因为它让我看起来不那么愚蠢;-)如果您正在实现运算符+,那么它意味着您需要一个新对象。它实际上只对具有值语义的对象有意义,所以切片不应该是一个真正的问题。如果这是一个问题,您可能不希望实现具有典型运算符+语义的东西。