In const member functions a top level const qualifier is applied to each member of the class, unless the member is marked as mutable (which means never const).
You can also have volatile member functions and both volatile and const.
Note, that for pointers and references the behaviour may be surprising:
struct X {
int a;
int* pa;
int& ra;
X()
: a(1)
, pa(&a)
, ra(a)
{}
void foo() const {
*pa = 2; // Ok, this is the pointer being const, not the value being pointed to.
ra = 3; // Ok, this is the reference being const, not the value being referenced.
a = 4; // Error, a is const
pa = &a; // Error, pa is const.
}
};
Below is how top level const qualifier is applied:
int becomes int const - a constant integer.
int* becomes int* const - a constant pointer, not int const* - a pointer to constant.
int& becomes int& const - a constant reference, not int const& - a reference to constant. Applying const to references does not do anything, because they can not be changed to refer to another object anyway.
Another way to think about this, is that in non-const member functions this has the type of X* const, whereas in const member functions this is X const* const. Note how this pointer is always constant.