What are top-level const qualifiers?
Solution 1:
A top-level const qualifier affects the object itself. Others are only relevant with pointers and references. They do not make the object const, and only prevent modification through a path using the pointer or reference. Thus:
char x;
char const* p = &x;
This is not a top-level const, and none of the objects are immutable.
The expression *p
cannot be used to modify x
, but other expressions
can be; x
is not const. For that matter
*const_cast<char*>( p ) = 't'
is legal and well defined.
But
char const x = 't';
char const* p = &x;
This time, there is a top-level const on x
, so x
is immutable. No
expression is allowed to change it (even if const_cast
is used). The
compiler may put x
in read-only memory, and it may assume that the
value of x
never changes, regardless of what other code may do.
To give the pointer top-level const
, you'd write:
char x = 't';
char *const p = &x;
In this case, p
will point to x
forever; any attempt to change this
is undefined behavior (and the compiler may put p
in read-only memory,
or assume that *p
refers to x
, regardless of any other code).
Solution 2:
int *const i
puts const
at the top-level, whereas int const *i
does not.
The first says that the pointer i
itself is immutable, whereas the second says that the memory the pointer points to is immutable.
Whenever const
appears immediately before or after the type of the identifier, that is considered a top-level qualifier.
Solution 3:
The way it was explained to me, given:
[const] TYPE * [const] VARIABLE
VARIABLE is used to point to data of type TYPE through *VARIABLE
Draw a line through the *
or multiple *
s
- If there is a
const
to the left of the*
it applies to the data and the data cannot be changed:*VARIABLE
cannot be assigned, except at initialization - If there is a
const
to the right of the*
it applies to the VARIABLE and what the VARIABLE points to cannot be changed:VARIABLE
cannot be assigned, except at initialization
So:
| left right
int * i1;
| no no can change *i1 and i1
int const * i2;
| yes no cannot change *i2 but can change i2
int * const i3;
| no yes can change *i3 but i3 cannot be changed
int const * const i4;
| yes yes cannot change *i4 or i4
Solution 4:
The two levels of const are: * Low-level Const * Top-level Const
You should look at top and low level const through references and pointers, because this is where they are relevant.
int i = 0;
int *p = &i;
int *const cp = &i;
const int *pc = &i;
const int *const cpc = &i;
In the code above, there are 4 different pointer declarations. Let's go through each of these,
int *p
: Normal Pointer can be used for making changes to the underlying object and can be reassigned.
int *const cp
(top-level const): Const Pointer can be used for making changes to the underlying object but cannot be reassigned. (Cannot change it to point to another object.)
const int *pc
(low-level const): Pointer to Const cannot be used for making changes to the underlying object but can itself be reassigned.
const int *const cpc
(both top and low-level const): Const Pointer to a Const can neither be used for making changes to the underlying object nor can itself be reassigned.
Also, top-level const is always ignored when assigned to another object, whereas low-level const isn't ignored.
int i = 0;
const int *pc = &i;
int *const cp = &i;
int *p1 = cp; // allowed
int *p2 = pc; // error, pc has type const int*
Hope this helped :) FYI: C++ Primer has a lot of information about the same!!!