C/C++ - const with Pointer or Reference
const
with Normal Variables
Two ways to add const
for normal variables:
const TYPE NAME = VALUE; // more common
TYPE const NAME = VAULE;
Both means this variable cannot be assigned to another value.
For example,
#include <iostream>
using namespace std;
int main(void)
{
const int i = 1;
int const j = 1;
i = 2; // error
j = 2; // error
cout << "i = " << i << endl;
cout << "j = " << j << endl;
return 0;
}
The same error cames out for i
and j
:
const.cpp:9:4: error: cannot assign to variable 'i' with const-qualified type 'const int'
i = 2;
~ ^
const.cpp:7:12: note: variable 'i' declared const here
const int i = 1;
~~~~~~~~~~^~~~~
const.cpp:10:4: error: cannot assign to variable 'j' with const-qualified type 'const int'
j = 2;
~ ^
const.cpp:8:12: note: variable 'j' declared const here
int const j = 1;
~~~~~~~~~~^~~~~
2 errors generated.
const
and Reference
Also two ways to add const
to a reference:
const TYPE &NAME = VALUE; // more common
TYPE const &NAME = VAULE;
Both have the same meaning.
There are two limits for them:
- This reference cannot be assigned to another variable
- The variable being referenced cannot change its value with this reference,
but it can change its value without using that reference.
For example,
#include <iostream>
using namespace std;
int main(void)
{
int i = 1, j = 2;
int const &r1 = i;
const int &r2 = i;
// change value with reference
r1 = 3; // error
r2 = 3; // error
// change value
i = 4;
// change reference object
r1 = j; // error
r2 = j; // error
return 0;
}
constant reference can only be read.
if the value of the variable it referenced to has be changed,
it can only change the value without that reference.
const
and Pointer
This one is complicated.
But we can use the position of const
to remember which one const
is decorating:
TYPE* const pNAME; // 1
TYPE const *pNAME; // 2
const TYPE *pNAME; // 3
const TYPE* const pNAME; // 4
For 1,const
decorates pNAME
,
that means pNAME
cannot be changed (No pNAME = ...
).
For 2,const
decorates *pNAME
,
so *pNAME
cannot be changed (No *pNAME = ...
).
For 3,const
decorates TYPE *pNAME
.
it is the same as 2,
saying that *pNAME
cannot be changed (No *pNAME = ...
).
For 4,const
decorates pNAME
and TYPE*
,
so both pNAME
and TYPE*
cannot be changed (No pNAME = ...
or *pNAME = ...
).
#include <iostream>
using namespace std;
int main(void)
{
int i = 1, j = 2;
int* const p1 = &i;
int const *p2 = &i;
const int *p3 = &i;
const int* const p4 = &i;
// change value with pointer
*p1 = 2;
*p2 = 2; // error
*p3 = 2; // error
*p4 = 2; // error
// change value
i = 3;
// change pointer position
p1 = &j; // error
p2 = &j;
p3 = &j;
p4 = &j; // error
return 0;
}