Typedef
You can give a new name to a type using typedef. Declaration typedef existingType newName;makes newName refer to existingType. For example, typedef int* IntPtr;makes IntPtr mean int*. Declaration IntPtr p;creates variable p of type int*. |
What typedef means
A type definition does not call for a textual substitution. Recall that declaration int* p, q;says that p has type int* and q has type int. But IntPtr p, q;says that p and q both have type IntPtr, which is the same as int*. As you can see, having names for pointer types can make a program clearer. You typically make type definitions outside of functions, often in header files. |
Const pointers
Creating an integer constant
const int size = 50;makes it clear that you cannot change the value of 'size'. But what about the following? int x = 25; const int* p = &x;Does the const designator indicate that you cannot change p or that you cannot change *p? Would we have to say that x is a constant to do that? According to the definition of C++, declaration const int* p = &x;says that the program cannot use variable p to change *p. Statements
int x = 25;
const int* p = &x;
*p = 3;
are not allowed because the third one tries to change variable *p.
You are allowed to change the pointer that is stored in a const pointer variable. For example, there is nothing wrong with int x = 25, y = 35; const int* p = &x; … p = &y; Clearly, it is *p that is constant, not p itself. |
A const pointer can point to a nonconst variable
There is nothing wrong with creating a const pointer to a non-const variable.
For example,
int x = 25; const int* p = &x; x = 3;is fine. The issue is how the program refers to the variable; *p is const but x is not. You are always free to add a const restriction, but you cannot take it away. |
You cannot copy a const pointer into a nonconst variable
Suppose you want to do a loop using a pointer. It might
look something like this.
void loop(const int* ptr) { const int* p = ptr; while(…) { … p = … } }The details suppressed with dots are not important here. The point is that variable p must be a const pointer, since it is set equal to a const pointer. You can still change the pointer that is in p. You just can't change *p. |
Now comes a surprising part of this discussion.
Const with a typedef'd pointer type
After
typedef int* IntPtr; const IntPtr p;you find that you are allowed to change *p but you are not allowed to change p. Types const int* and const IntPtr are different! |
Creating const pointer types
You can get around that strange behavior by doing
more typedefs. Declarations
typedef int* IntPtr; typedef const int* ConstIntPtr;creates two types. Type ConstIntPtr is just like const int*, and declaration ConstIntPtr p;has exactly the same meaning as const int* p;Declaration ConstIntPtr p, q;means the same thing as const int* p; const int* q; |
Declaration
typedef oldtype newnamemakes newname refer to oldtype.
Declaration
const double* q = ptr;means that you cannot use q to change what is stored in variable *q. But you can change the memory address that is stored in q.
Modifier const works differently when it modifies a type name that is defined by typedef.