|
C++ lets you 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*. Then, declaration
IntPtr p;
creates variable p of type int*.
You typically make type definitions outside of functions,
often in header files.
A type definition does not call for a textual substitution. It treats the new type as atomic, or as a unit. 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.
Now comes a surprising part of this discussion.
After declarations
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! Since IntPtr is a pointer type, const IntPtr indicates that the pointer itself is a constant.
Type const IntPtr is usually not what you want, which is a type that is equivalent to const int*. You can get that by doing a separate typedef. Declaration
typedef const int* ConstIntPtr;says that ConstIntPtr is equivalent to const int* and
ConstIntPtr p, q;
has exactly the same meaning as
const int *p, *q;
Do not define a type that is already defined. Typically, that is relevant in modules, the topic of the next page. Do not define a type both in a header file stuff.h and in the associated implementation file stuff.cpp. The standards require that.
A more basic way to use const in C++ is to write const after the part of a type that it modifies.
int const * p;
Here, const immediately follows int.
It is the variable of type int that cannot
by modified (using p). So, if y has
type int, then
p = &y;is allowed, but *p = 0;is not. |
int * const q = s;
Here, const immediately follows *.
It is the pointer that cannot
by modified (using q). So, if y
has type int, then
q = &y;is not allowed, but *q = 0;is allowed. |
int const * const r = s;
Here, neither
r = &y;nor *r = 0;is allowed. |
const int * s;
When const is written before a type,
it applies to the first part of the type.
So type const int * is the same as
int const *.
As you can see, the compiler moves const across the first part of the type. |
const IntPtr s;
Here, the compiler moves const across the first part of the type. But that gives type IntPtr const. Replacing IntPtr by int * gives type int * const. It is the pointer that cannot be changed. |
|