C++ - 如何重载operator + =?

q09*_*987 22 c++

给出以下代码片段,

class Num
{
public:
    Num(int iNumber = 0) : m_iNumber(iNumber) {}

    Num operator+=(const Num& rhs)
    {
        this->m_iNumber = (this->m_iNumber + rhs.m_iNumber);
        return *this;
    }
private:
    int m_iNumber;
};

//===========================================================
int _tmain(int argc, _TCHAR* argv[])
{
    Num a(10);

    Num b(100);

    b += a;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我想知道如何正确超载operator+=.

问题:

  1. 如何定义此运算符的签名?特别是,什么应该用于返回值?

  2. 如何实现功能体?

  3. 如何使用这个重载运算符?

我已经提供了上述解决方案,但我担心这是不正确的.

Pra*_*rav 36

通过引用返回会更好

Num& operator+=(const Num& rhs){

      this->m_iNumber += rhs.m_iNumber;
      return *this;
}
Run Code Online (Sandbox Code Playgroud)

  • @ q0987:任何赋值的结果通常返回赋值中最左边的变量.如果你返回一个引用,那就是你真正在做的事情.如果返回值,则返回最左侧赋值的*副本*而不是实际值.那就是'Num a(10); (a + = Num(10))= 100;`导致`a`的内容为'20`而不是某些程序员可能期望的'100`. (6认同)
  • 你好Prasoon,通过引用返回有什么好处,你怎么能用它?我假设"按引用返回"允许用户更改内部数据.谢谢 (3认同)
  • @ q0987:此外,通过引用返回将不会创建对象的副本(按值返回),因此不会对复制c-tor进行任何调用.然而,在大多数情况下,现代编译器会忽略副本.了解RVO(返回值优化). (3认同)
  • 为什么返回类型不能为void?该函数不应该只为类的当前实例中的属性赋值吗?为什么我们需要返回一个指向实例的指针?如果是这样,为什么是指针而不是对象本身?编辑:我想我明白了......在正常的演讲中:就像“+”运算符返回两者之和一样,“+=”应该既:分配给左操作数并返回它改变的值;也就是说,最左边的值...如果有人认为他可以添加任何相关内容,请这样做 (2认同)

JUS*_*ION 8

如果您关注这个Wikibook,您将通过示例找到这些答案:

  1. Type& operator+=(const Type& right) 是正确的签名.
  2. 你做得对.
  3. 您使用重载运算符就像普通运算符一样,仅适用于您的类型.这就是练习的重点.;)

注意作为一个附加点(你做得对),复合赋值运算符必须是成员函数.

  • 实际上复合赋值运算符可以是非成员函数。这在由于某种原因无法提供成员函数的情况下很有用。例如枚举(这是我遇到这个时正在寻找的)。请参阅此处有关重载的有用讨论 (http://stackoverflow.com/questions/4421706/operator-overloading/4421729#4421729) (2认同)

tem*_*def 5

任何赋值运算符(operator= 或 operator @= 代表您最喜欢的运算符 @)的签名应该是

Class& operator @= (const Class& rhs);
Run Code Online (Sandbox Code Playgroud)

也就是说,该函数通过 const 引用获取其参数(因为它不会修改它),然后返回对该对象的可变引用。您返回非常量引用的原因是,由于历史原因,您可以编写如下代码:

(a += b) += c;
Run Code Online (Sandbox Code Playgroud)

这绝不是好的风格,但它适用于整数,因此您应该努力使其也适用于您的类型。

至于你的函数体,你有什么是完全正确的。但是,一般而言,即使参数是接收器对象,您也应该确保代码有效。例如,如果你写这样的东西

a += a;
Run Code Online (Sandbox Code Playgroud)

这被翻译成

a.operator+= (a);
Run Code Online (Sandbox Code Playgroud)

因此,代码将在参数和接收器都是同一个对象的情况下进行操作。这对于复合赋值运算符通常不会出现(通常只operator=需要担心这一点),但在某些情况下,如果您不小心,您可能会被烧毁。

最后,您可以operator +=像在上面的示例代码中一样使用此函数。任何使用+=自动调用它。

希望这可以帮助!

  • 迂腐、挑剔,但我们通常更喜欢使用“@”而不是“#”来表示任意运算符,以避免在语法高亮中触发“注释模式”。:) (2认同)