C++ Const Usage Explanation
Solution 1
Read this: https://isocpp.org/wiki/faq/const-correctness
The final const
means that the function Method3
does not modify the non mutable members of its class.
const int* const
means a constant pointer to a constant int: i.e. a pointer that cannot be changed, to an int that cannot be changed: the only difference between this and const int&
is that it can be null
const int* const&
means a reference to a constant pointer to a constant int. Usually pointers are not passed by reference; const int* &
makes more sense because it would mean that the pointer could be changed during the method call, which would be the only reason I can see to pass a pointer by reference, const int* const&
is to all intents and purposes the same as const int* const
except that it is probably less efficient as pointers are plain old data (POD) types and these should, in general be passed by value.
Solution 2
It's easier to understand if you rewrite that as the completely equivalent
// v───v───v───v───v───v───v───v───v───v───v───v─┬┐
// ││
// v──#1 v─#2 v──#3 v─#4 #5
int const * const Method3(int const * const&) const;
then read it from right to left.
#5 says that the entire function declaration to the left is const
, which implies that this is necessarily a member function rather than a free function.
#4 says that the pointer to the left is const
(may not be changed to point to a different address).
#3 says that the int
to the left is const
(may not be changed to have a different value).
#2 says that the pointer to the left is const
.
#1 says that the int
to the left is const
.
Putting it all together, you can read this as a const
member function named Method3
that takes a reference to a const
pointer to an int const
(or a const int
, if you prefer) and returns a const
pointer to an int const
(const int
).
(N.b. #2 is entirely superfluous.)
Solution 3
First of all const T
is equivalent to T const
.
const int* const
is therefore equivalent to int const * const
.
When reading expressions with lots of const
tokens and pointers in them, always try to read them from right to left (after applying the transformation above). So in this case the return value is a const pointer to a const int
. Making the pointer itself const
makes no sense here since the return value isn't a lvalue that could be modified. Making the pointee const
, however, guarantees that the caller may not modify the int
(or array of int
s) returned by Method3
.
const int*const&
becomes int const*const&
, so it is a reference to a const pointer to a const int
. Passing a const pointer by references male no sense either - you can't modify the referenced value since the pointer is const
and references and pointers occupy equal storage so there aren't any space savings either.
The last const
indicates that the method does not modify the this
object. The this
pointer within the method body will have the (theoretical) declaration T const * const this
. This means that a const T*
object will be able to call T::Method3()
.
Solution 4
An easy way to remember the rules of const
is to think about it this way: const
applies to the thing on its left, unless there's nothing on its left.
So in the case of const int * const
, the first const has nothing on its left, so it applies to int
and the second one does have something on its left, so it applies to the pointer.
This rule also tells you what would happen in the case where you have const int const *
. Since both const's apply to int
this expression is redundant and therefore invalid.
Solution 5
I like to use the "clock" or "spiral" method where starting from the identifier name (in this case Method3
) you read back-and-forth from left-to-right-back-to-left, etc. in order to decode naming conventions. So const int* const Method3(const int* const&) const
is a class method that doesn't change any class members (of some un-named class) and takes a constant reference to a pointer that points to a constant int
and returns a constant pointer to a constant int
.
Hope this helps,
Jason
Related videos on Youtube
RoR
Updated on July 08, 2022Comments
-
RoR almost 2 years
const int* const Method3(const int* const&) const;
Can someone explain the usage of each of the const?
-
Jason about 13 yearsI really like this method for deciphering complicated declarations: c-faq.com/decl/spiral.anderson.html
-
-
T.E.D. about 13 yearsVoting up this (and the similar answer of ildjarn), in part for making the point that the whole thing makes more sense if you don't put the first
const
s at the head of the phrase. This is precisely why I think it is bad practice to putconst
there, even though the language allows it, and it is the most common usage. -
scatter almost 3 years"const int* const means a constant pointer to a constant int: i.e. a pointer that cannot be changed, to an int that cannot be changed" Slight correction. Things pointed to by a
const int*
can still be changed, just not via that pointer.int x = 1; const int* p = &x; x = 2;
succeeds, while*p = 2
fails.