Reputation: 195
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..?
Upvotes: 1
Views: 183
Reputation: 101181
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.
Upvotes: 3
Reputation: 310980
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;
}
Upvotes: 4