#include
using namespace std;
int main(int argc, char* argv[])
{
int i1 = 0;
int i2 = 10;
const int *p = &i1;
int const *p2 =
const int *p = &i1;
int const *p2 = &i1;
These both declare non-const pointers to const data.
That is, using p
, you cannot change the data it points to. However, you can change the pointer itself, for example, by assigning as p = &i2
which is legal. But *p = 87987
is illegal, as the data p
points to is const!
--
int * const p = &i1;
This declares const pointer to non-const data. That is, p=&i2
is illegal, but *p = 98789
is legal.
--
const int * const p = &i1;
This declares const pointer to const data. That is, now both p=&i2
and *p=87897
are illegal.
int const * is the same as const int *
With the help of pointer, you can actually do two things.
Now, when you say, int const* ptr or int const* ptr, it falls under first category. It's same as -
const int num = 5; // Both mean the same.
int const num = 5;
To, actually not able to change to a different location, i.e., pointer to a constant location but be able to modify the data, the semantics should be int* const
. Since the content of the pointer is a constant, it should be initialized while declaration.
int num = 5;
int* const ptr; // Wrong
ptr = # // Wrong
int* const ptr = #
*ptr = 100;
However, there is a third kind. Constant pointer to a constant location, which can neither point to a different memory location nor change the data it is pointing to. ( i.e., const int* const )
And now answering the questions, the first two can be compiled because they are not pointing to constant locations. So, they can be modified at later stages too.
const int const *p3 = &i1;
p3 = &i2; // Wrong
In the above snippet, p3
is a constant pointer to a constant location. So, it cannot be modified.
const
at the end of a member function says it is not going to change the state of the object. When you say *p = 1;
, you are not changing the state of the object. p
still points to the same memory location. This is not allowed to do -
int const * Coo2::getP() const
{
*p = 1; // State of `p` is still not modified.
p = new int ; // Error: Changing the memory location to which p points.
// This is what changing the state of object mean and
// is not allowed because of `const` keyword at the end of function
return this->p;
}
Hope, now you understand why the program compiles :)
The two are exactly the same. What matters is the position of the qualifier relative to the asterisk (*
):
int const *p; // normal pointer to const int
const int *p; // ditto
int *const p; // const pointer to normal int (rarely useful)
int const * const p; // const pointer to const int
Succinctly; each combination of read/write int & pointer;
int main() {
int a,b;
int* w; // read/write int, read/write pointer
w= &b; // good
*w= 1; // good
int* const x = &a; // read only pointer, read/write int
// x = &b; // compilation error
*x = 0; // good
int const * y; // read/write ptr, read only int
const int * y2; // " " "
y = &a; // good
// *y = 0; // compilation error
y2 = &a; // good
// *y2 = 0; // compilation error
int const * const z = &a; // read only ptr and read only int
const int * const z2 = &b; // " " " "
// *z = 0; // compilation error
// z = &a; // compilation error
// *z2 = 0; // compilation error
// z2 = &a; // compilation error
}
No, the const
keyword before the * means that the variable you are pointing to is a "const" variable and only it can not be modified.
Foo* const p = &bar;
const Foo* const p = &bar
It is perfectly fine to have a pointer of const int* foo
be assigned to a pointer of const int* const bar
just like it is fine to have an int
's value assigned to a const int
. Think of it in the same manner.