在C++中重载运算符+

5

好的,我正在阅读一本书,尝试学习C++运算符重载。我创建了一个BigInt类,它接受一个单独的int(最初设置为0)作为构造函数。我重载了+=方法,在以下代码中它可以正常工作:

BigInt x = BigInt(2);
x += x;
x.print( cout );

代码将输出4。然后,我正在使用以下代码重载全局运算符+:
BigInt operator+(const BigInt lhs, const BigInt rhs)
{
    BigInt returnValue(lhs);
    returnValue += rhs;
    return returnValue;
}

这对以下代码也适用:

这也适用于以下代码:

BigInt x = BigInt(1);
BigInt y = BigInt(5);
BigInt z = x + y;
z.print();

这会打印出6。然而,当我尝试执行以下代码时,它就无法工作。该书解释得不是很清楚,并暗示它应该可以简单地工作。

BigInt x = BigInt(1);
BigInt z = x + 5;
z.print();

这将打印出1。我不确定z为什么是1,因为应该是6。我在网上和stackoverflow上搜索过,但没有找到其他人有完全像我这样的问题。有些接近,但答案并不适合。非常感谢任何帮助!


4
我认为这与您的问题无关,但出于效率考虑(并且因为这在C++中是习惯用法),operator+ 的参数应该通过const引用而不是按值传递,例如 BigInt operator+(const BigInt& lhs, const BigInt& rhs) - Tyler McHenry
3
有一件事情一直让我想知道:为什么你要写= BigInt(1)而不是= 1?如果您展示完整的类定义,我们可以更好地帮助您 :) - Johannes Schaub - litb
1
我同意Tyler的观点。使用“BigInt x(1);”进行初始化更加习惯用法。你现在的做法会创建一个临时对象,然后调用拷贝构造函数(尽管这可能会被优化掉)。 - Dan
字面值“5”不是 BigInt(错误的类型)。 - mingos
2
@Tyler。实际上,最好的选择是通过值传递lhs,并通过const引用传递rhs(如果您将在函数内部复制lhs,只需将该副本移动到接口即可。这将为编译器提供消除复制的机会,如果lhs是临时的)。 - David Rodríguez - dribeas
显示剩余2条评论
4个回答

3
最有可能的问题在于+=运算符。请发一下相关代码。

当@Johannes Schaub说它是通过隐式转换进行转换时,他是正确的(许多断点和代码跟踪为我找到了这个问题)。问题实际上在于+=运算符。如果没有早期评论和@aaa的帮助,我无法想出解决方法。谢谢你们两个! - user131441

2
您需要为BigInt添加int类型的重载;您示例中的常量5是int类型,而不是BigInt类型。以下代码应该可以解决问题:
BigInt operator+(const BigInt lhs, const int rhs)
{
    BigInt returnValue(rhs);
    returnValue += lhs;
    return returnValue;
}

你可能也需要为 operator+(const int lhs, const BigInt rhs) 创建一个函数。

4
代码编译意味着将其转换为BigInt类型已经成功(通过隐式转换方式)。为什么代码会编译并打印出1?这对我来说没有意义。 - Johannes Schaub - litb
是的,除非存在一个以int为参数的非explicit构造函数,即提供了从intBigInt的转换,否则您需要三个operator+的重载。@kevingessner,在参数列表中int前面的const有点无用。另一方面,返回类型应该是const BigInt,以避免像a+b=c;这样的荒谬行为。 - Nikolai Fetissov

1
以下是超级简化的代码(我可以添加的最少量,以包含您的所有代码并将其转换为有效的独立可执行程序):
#include <iostream>

class BigInt
{
  public:
    BigInt(int i): _i(i) {}
    void print() { std::cout << "BigInt(" << _i << ")\n"; }
    void operator +=(const BigInt rhs) { _i += rhs._i; }
  private:
    int _i;
};

BigInt operator+(const BigInt lhs, const BigInt rhs)
{
    BigInt returnValue(lhs);
    returnValue += rhs;
    return returnValue;
}

int main() {
  BigInt x = BigInt(1);
  BigInt y = BigInt(5);
  BigInt z = x + y;
  z.print();

  BigInt ax = BigInt(1);
  BigInt az = ax + 5;
  az.print();

  return 0;
}

发出,如预期:

BigInt(6)
BigInt(6)

请尽可能少地更改此工作代码以重现您观察到的错误 - 这当然会显示您的错误确切位置。

0
你发布的代码看起来很好,应该可以正常工作。你看到的问题几乎肯定是由于 BigInt 类的复制构造函数或赋值运算符引起的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接