为什么需要在跟随运算符重载时使用const?

时间:2016-11-04 14:19:54

标签: c++

这是添加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对象,我收到错误。那是为什么?

2 个答案:

答案 0 :(得分:2)

让我们假设我们写了这个函数:

friend Integer operator+(Integer& a, Integer& b);

从风格上讲,这并不是很好,因为operator+不应该修改其论点。但是,让我们说我们不关心这一点。现在,当我们尝试这样做时会发生什么:

Integer d = a + b + c;

这被归为(a+b)+ca+b子表达式会找到我们的operator+(),这是一个可行的函数,因为ab是非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 &IntegerInteger &&。第二个是不建议的,因为它会创建一个对象的副本(虽然,有时这是你想要的!),后者不建议,因为它会拒绝接受持久对象。那么,第一个选项是最好的,因为它将接受任何Integer对象,无论它是否到期。

推荐阅读:What are rvalues, lvalues, xvalues, glvalues, and prvalues?它非常详细,可能需要多次通过才能获得&#34;得到&#34;它,但它对任何C ++程序员来说都是非常有价值的知识。