运算符重载中按值传递错误

Error passing by value in operator overloading

我试图理解为什么在简单的 class 定义中按引用传递有效而按值传递无效

#include <iostream>

class Rettangolo {
  int a, b;
  public:
    Rettangolo (Rettangolo& r) {
      a = r.a;
    }
    Rettangolo (int _a, int _b) : a(_a), b(_b) {};
    Rettangolo operator+= (Rettangolo r1);
    void print() {
      std::cout << a << ", " << b;
    }
};

Rettangolo Rettangolo::operator+= (Rettangolo r1) {
  a += r1.a;
  b += r1.b;
  return *this;
};

int main() {
  std::cout << "Hello World!\n";
  Rettangolo recta (1, 2);
  Rettangolo rectb (5, 6);
  recta += rectb;
  recta.print ();
}

如果我在 operator+= 的参数中使用 (Rettangolo r1),如上例所示,输出为“6,2”。 但是如果我在参数中使用 (Rettangolo& r1) 输出是“6, 8”,正如我所期望的那样

这是因为你的拷贝构造函数没有完全发挥作用。它只复制 a,而不是 b。因此,当您调用 operator+= 时复制 rectb,按值传递 rectba 被复制并添加到 recta,但 b未复制,因此未添加到 recta。要解决此问题,请在复制构造函数中添加 b 复制,或者只是删除它,编译器将为您生成一个默认的复制构造函数,它会复制 ab.

您的代码存在几个问题。

最重要的问题是您的复制构造函数根本没有复制 b。当您将 Rettangolo 按值 传递给 operator+= 时,编译器必须复制它,因此在您的 operator+= 中复制的 r1.b 值有一个 indeterminate 值,在您的情况下恰好为 0,但这不能保证。通过引用传递 r1 而不是跳过损坏的复制构造函数。

此外,复制构造函数和 operator+= 需要通过 const 引用获取 Rettangolo

此外,您的 operator+= 没有通过引用返回 *this,因此它返回了另一个副本(您忽略了)。

试试这个:

#include <iostream>

class Rettangolo {
  int a, b;
  public:
    Rettangolo (int _a, int _b) : a(_a), b(_b) {}

    Rettangolo (const Rettangolo& r) : a(r.a), b(r.b) {}
    // or: Rettangolo (const Rettangolo &r) = default;
    // or: simply omit this constructor and let the compiler generate it for you!

    Rettangolo& operator+= (const Rettangolo &r1);

    void print() const {
      std::cout << a << ", " << b;
    }
};

Rettangolo& Rettangolo::operator+= (const Rettangolo &r1) {
  a += r1.a;
  b += r1.b;
  return *this;
};

int main() {
  std::cout << "Hello World!\n";
  Rettangolo recta (1, 2);
  Rettangolo rectb (5, 6);
  recta += rectb;
  recta.print ();
}