这是添加3个Integer类对象的代码
#include <iostream>
using namespace std;
class Integer
{
int value;
public:
Integer(int i)
{
value = i;
};
int getValue()
{
return value;
}
friend Integer operator+(const Integer & a,const Integer & b)
{
Integer i(a.value+b.value);
return i;
}
};
int main()
{
Integer a(1), b(2), c(3);
Integer d = a + b + c; //****HERE****
cout << d.getValue() << endl;
return 0;
}
有人可以解释为什么在这种情况下将const添加到参数中。如果我删除const,在编译期间我得到二进制操作错误的无效操作数。 添加到这个问题: 当我只添加一个没有const的a和b时,输出为3而没有任何错误。但是,添加3个+ b + c对象,我收到错误。那是为什么?
答案 0 :(得分:2)
让我们假设我们写了这个函数:
friend Integer operator+(Integer& a, Integer& b);
从风格上讲,这并不是很好,因为operator+
不应该修改其论点。但是,让我们说我们不关心这一点。现在,当我们尝试这样做时会发生什么:
Integer d = a + b + c;
这被归为(a+b)+c
。 a+b
子表达式会找到我们的operator+()
,这是一个可行的函数,因为a
和b
是非const
类型为Integer
的左值,并且该表达式的结果是类型Integer
的右值。
后续表达式为{some rvalue Integer} + c
。 那个表达式我们无法找到可行的功能。虽然c
可以绑定到Integer&
,但第一个参数不能 - 您可以将rvalue绑定到非const
左值引用。所以你必须写下这样的东西:
Integer tmp = a + b; // OK
Integer d = tmp + c; // also OK
但是现在我们将这个额外的名称引入我们的范围,并在我们的代码中添加一个额外的声明,以解决我们的函数签名的不可靠性。
答案 1 :(得分:2)
因为你试图将Temporary绑定到[non-const-]引用,这在C ++中是不允许的。
在代码Integer d = a + b + c;
中,首先评估a + b
,然后创建一个新的临时对象,然后根据c对其进行评估。然后代码变为Integer d = t<a+b> + c;
。由于第一个对象现在是临时对象,因此只有三个函数签名会将其作为参数接受:const Integer &
,Integer
和Integer &&
。第二个是不建议的,因为它会创建一个对象的副本(虽然,有时这是你想要的!),后者不建议,因为它会拒绝接受持久对象。那么,第一个选项是最好的,因为它将接受任何Integer
对象,无论它是否到期。
推荐阅读:What are rvalues, lvalues, xvalues, glvalues, and prvalues?它非常详细,可能需要多次通过才能获得&#34;得到&#34;它,但它对任何C ++程序员来说都是非常有价值的知识。