简体   繁体   中英

Question about const member functions in c++

Can anyone explain me this error? Here is the code:

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;
}

When I try to compile I get this error:

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&'

Can anyone explain me this? If I add const qualifier to the argument of the += operator, it compiles. So I think the problem is that I'm passing a reference to item to the += opertor, which is non const, inside the const function fun(). Can anyone explain me why this is illegal, and how I can avoid to do this kind of mistakes, if for instance there is some rule of thumb to follow when using const qualifiers, etc..?

This member function

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

is a constant member function. So members of the object to which the function is called are considered as constant members in particular the data member item in this case is considered as it was declared like

const O item;

In this expression

j += item;

there is used the member function

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

that accepts a non-constant reference to an object of the type O. So in fact you are trying to bind a non-constant reference to a constant object. So the compiler issues an error.

The parameter of the above operator should be declared with the qualifier const and has a return statement as for example

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

In many places the const keyword is a promise that [some code] wont chjange the state of the thing marked const . By contrast the lack of the keyword had to be interpreted as meaning [some code] might change the state of that thing.

The compiler checks to see if these promises are consitent, and complains if they are not.

In this case you have a declaration

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

where you don't promise to keep the argument object constant. And because this is a reference argument you are not promising to leave the things refered to alone.

But you try to call that operation from the context

void A::fun() const;

which does promise to keep the state of the calling object constant and then uses one of it's members ( A::item ) as the argument to O::operator+ .

The compiler is complaining that you promised in one place to keep A::item constant and in another have not made that guarantee.

becasuse O::operator+= doesn't actually change it's argument, you can fix the issue by changing the signature to

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

Done and dusted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM