8
#include <iostream> using namespace std; int main(int argc, char* argv[]) { int i1 = 0; int i2 = 10; const int *p = &i1; int const *p2 = &i1; const int const *p3 = &i1; p = &i2; p2 = &i2; p3 = &i2; cout << *p << endl << *p2 <<endl << *p3 <<endl; return 0; } 

The code can be compiled with both VC6.0 and VC2010. But I have questions as blow:

const int *p = &i1;

It means what the "p" points can not be modified,but p can not be modified,am I right? so

p = &i2;

this line can be complied,yes?

This line:

int const *p2 = &i1; 

In my mind,this means p2 can not be modified while what p2 points can be changed, am i right? Why the

p2 = &i2;

can be compiled?

About this line:

const int const *p3 = &i1;

p3 = &i2;

Oh,god... I am crazy. I have no idea why this line can be compiled with no error... Can any body help me?

Another code which confused me is here:

class Coo2 { public: Coo2() : p(new int(0)) {} ~Coo2() {delete p;} int const * getP() const { *p = 1; return this->p; } private: int* p; }; 

why this code can be compiled? In

int const * getP() const

I have change the value or *p !

2
  • const applies to the thing to the left, unless there is nothing to the left in which case it applies to the thing on the right. (Yes, this is unnecessarily confusing and silly.) Commented Mar 11, 2011 at 3:07
  • const in the end means no change will be made to the object/class. Commented Mar 11, 2011 at 3:21

9 Answers 9

10

Here we consider 4 types of pointers declarations:

  1. int * w; It means that w is a pointer to an integer type value. We can modify both the pointer and its content. If we initialize w while declaration as below: int * w = &a;
    Then, both of below operations are viable:
    w = &b;(true)
    *w = 1;(true)

  2. int * const x;
    It means x is a constant pointer that points to an integer type value. If we initialize x while declaration as below:
    int * const x = &a;
    Then, we cannot do: x = &b;(wrong) because x is a constant pointer and cannot be modified.
    However, it is possible to do: *x = 1;(true), because the content of x is not constant.

  3. int const * y; //both mean the same
    const int * y;
    It means that y is a pointer that points to a constant integer value. If we initialize y while declaration as below:
    int const * y = &a;
    Then, it is possible to do: y=&b;(true) because y is a non-constant pointer that can point to anywhere.
    However, we cannot do: *y=1;(wrong) because the variable that y points to is a constant variable and cannot be modified.

  4. int const * const z; //both mean the same
    const int * const z;
    It means that z is a constant pointer that points to a constant integer value. If we initialize z while declaration as below:
    int const * const z = &a;
    Therefore, non of below operations are viable:
    z = &b;(wrong)
    *z = 1;(wrong)

Sign up to request clarification or add additional context in comments.

Comments

5

With the help of pointer, you can actually do two things.

  1. You can change the data it is pointing to but cannot point to a different memory location.
  2. You can point it to a different memory location but cannot change the data it is pointing to.

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 = &num; // Wrong int* const ptr = &num; *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 :)

Comments

4

int const * p; and const int * p are the same. It is when the const comes after the * that the semantics of the expression change.

I know, it's crazy.

6 Comments

int const * getP() const, does the last constmeans i can not change *p(what the p is pointing)?
Ok, your attention to detail is getting in your way to learning the language (that's not a bad thing). When the const comest after a functions signature, it means that the member function (coloquily, one that is defined to belong to an object) intend not to make a change to to an object. The compiler enforces this intention to a certain degree. So if said function writes , or calls a function that may write to the object,in question, or in any other indirect (but detectable by the compiler) way the compiler will throw an error.
@Bug: No, that means the member function is const. Do you have a good introductory book?
@gman wow nice resource, I was about to leave him a comment to give a reference to Bjarne's book since he is so interested in the mechanics of the language:D
@Hassan Syed it means that the member function intend not to make a change to to an object. But I have change the value of *p in the second code section. Or the const means i can not change p?
|
2
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.

Comments

2

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 

2 Comments

The second code section: int const * getP() const, does the last constmeans i can not change *p(what the p is pointing)?
@BugCreater: No -- it's a qualifier on a member function, saying that function doesn't change the state of its object, so it can be called on a const object.
2

Here is a pointer to a constant:

 const int* p; 

The following statement is illegal, because it attempts to change the value of a constant:

 *p = 3; 

But this one is legal, because the pointer itself is not a constant:

 p = &x; 

On the other hand, this declaration shows a constant pointer to a variable.

 int* const p; 

In that case, the following statement is legal, as the variable can be changed:

 *p = 3; 

but this one is not, because it attempts to change the value of a constant.

 p = &x; 

Reference link:http://faculty.cs.niu.edu/~freedman/241/const-ptrs.txt

Comments

1

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.

  1. If you want a pointer that can't be reassigned then you need to declare it as Foo* const p = &bar;
  2. If you want a pointer that points to a "const" object that can't be reassigned declare it as 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.

Comments

1

int const * is the same as const int *

Comments

1

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 } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.