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;
}