Do class member reference variables have in-built “const-correctness”?
-
03-06-2021 - |
Question
struct A {
int &r;
A (int &i) : r(i) {}
void foo () const {
r = 5; // <--- ok
}
};
The compiler doesn't generate any error at r = 5;
.
Does it mean that &r
is already const-correct being a reference (logical equivalent of int* const
) ? [Here is one related question.]
La solution
I'm not sure exactly what you mean by "already const-correct", but:
Assigning to r
is the same as assigning to whatever thing was passed into the constructor of A
. You're not modifying anything in the instance of A
when you do this, so the fact that foo
is declared const isn't an obstacle. It's very much as if you'd done this:
struct A {
int * r;
A (int * i) : r(i) {}
void foo () const { *r = 5; }
}
The fact that foo
is const means that it doesn't modify anything in the A
instance it's called on. There's no conflict between that and having it modify other data it was supplied with.
Of course if you happened to arrange for r
to be a reference to some member of A
then calling foo
would modify the instance of A
after all. The compiler can't catch all possible ways in which const
ness of a member function might be violated; when you declare a member function const
you're promising that it doesn't engage in any such subterfuge.
Autres conseils
Yes, it's the logical equivalent of int* const
.
You may want to create and use appropriately qualified accessors in this case to prevent unwanted alterations to the value r
references.
I interpret a const
member function as implicitly inserting const
just to the left of every data member that doesn't already have such a qualifier. That const
is already there implicitly for references (int & const r;
is illegal syntax). In other words, references are "already const-correct" to use your nomenclature.
It would be nice if the const
qualifier on a member function had the affect of inserting const
in every possible valid position for every data member (e.g., data member int ** foo;
acts like int const * const * const foo;
in a const
member function), but that isn't what happens, and it isn't what the standard says will happen.