关于C ++中const成员函数的问题

时间:2019-12-09 19:04:46

标签: c++ class reference const const-reference

有人可以向我解释此错误吗? 这是代码:

class O{
    unsigned x;
    unsigned y;
    public:
        O(unsigned x_ ,unsigned  y_): x(x_), y(y_){
        };
        O& operator+= ( O & object){
            x += object.x;
        }
};

class A {
    O item;
    public:
        A(O i): item(i){;
        }
        void fun() const{
            O j(2,3);
            j += item;
        }
};

int main(){
    return 0;
}

当我尝试编译时,出现此错误:

In member function 'void A::fun() const':
[Error] no match for 'operator+=' (operand types are 'O' and 'const O')
[Note] candidate is:
[Note] O& O::operator+=(O&)
[Note] no known conversion for argument 1 from 'const O' to 'O&'

有人可以向我解释吗?如果将const限定词添加到+ =运算符的参数中,则会进行编译。所以我认为问题在于我正在const函数fun()中将对item的引用传递给+ =运算符,该运算符是非const的。谁能解释我为什么这是非法的,以及如何避免犯这种错误,例如,在使用const限定词等时要遵循一些经验法则。?

2 个答案:

答案 0 :(得分:4)

此成员函数

  void fun() const{
        O j(2,3);
        j += item;
    }

是常量成员函数。因此,调用该函数的对象的成员被视为常量成员,特别是在这种情况下,数据成员项被视为声明为

const O item;

在此表达式中

j += item;

使用了成员函数

    O& operator+= ( O & object){
        x += object.x;
    }

接受对类型O的对象的非常量引用。因此,实际上,您正在尝试将非常量引用绑定到常量对象。因此,编译器会发出错误消息。

上述运算符的参数应使用限定符const声明,并具有return语句,例如

    O& operator+= ( const O & object) {
        x += object.x;
        return *this;
    }

答案 1 :(得分:3)

在许多地方,const关键字是一个保证,[某些代码]不会改变标记为const的事物的状态。相比之下,缺少关键字必须解释为[某些代码] 可能会改变事物的状态。

编译器会检查这些承诺是否是有根据的,并抱怨它们是否是必需的。

在这种情况下,您有一个声明

O& O::operator+= (O & object);

不要在其中保证将参数object保持不变。而且,由于这是一个参考论点,因此您不能保证将所提及的内容保留下来。

但是您尝试从上下文中调用该操作

void A::fun() const;

这样做的 承诺保持调用对象的状态不变,然后使用其成员之一(A::item)作为O::operator+的参数。

编译器抱怨您在一个地方答应保持A::item不变,而在另一个地方没有保证。

由于O::operator+=实际上并没有改变其参数,因此您可以通过将签名更改为

来解决此问题。
O& O::operator+= (const O & object);

完成并撒粉。