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 mean 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 occurs 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
There are 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 restrictions for them:
- This reference cannot be reassigned to another variable
- The variable being referenced cannot have its value changed through this reference,
but its value can be changed without using this 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;
}A constant reference can only be read.
If the value of the variable it references has been changed,
it can only be changed without using that reference.
const and Pointer
This can be complicated.
However, we can use the position of const to determine what it is modifying:
TYPE* const pNAME; // 1
TYPE const *pNAME; // 2
const TYPE *pNAME; // 3
const TYPE* const pNAME; // 4
For 1,const modifies pNAME,
meaning that pNAME cannot be changed (i.e., pNAME = ... is not allowed).
For 2,const modifies *pNAME,
so the value pointed to by pNAME cannot be changed (i.e., *pNAME = ... is not allowed).
For 3,const modifies TYPE *pNAME.
This is the same as case 2, meaning that the value pointed to by pNAME cannot be changed (i.e., *pNAME = ... is not allowed).
For 4,const modifies both pNAME and the TYPE it points to,
so neither pNAME nor the value it points to can be changed (i.e., pNAME = ... or *pNAME = ... are not allowed).
#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 through pointer
*p1 = 2;
*p2 = 2; // error
*p3 = 2; // error
*p4 = 2; // error
// change value
i = 3;
// Change pointer's target
p1 = &j; // error
p2 = &j;
p3 = &j;
p4 = &j; // error
return 0;
}