我摘一段给你看看:
We do want to draw your attention to one slightly uncommon decision regarding the declaration of types, parameters, and variables. Clearly, several styles are possible:
void foo (const int &x);
void foo (const int& x);
void foo (int const &x);
void foo (int const& x);
Although it is a bit less common, we decided to use the order int const rather than const int for "constant integer." We have two reasons for this. First, it provides for an easier answer to the question, "What is constant?" It's always what is in front of the const qualifier. Indeed, although
const int N = 100;
is equivalent to
int const N = 100;
there is no equivalent form for
int* const bookmark; // the pointer cannot change, but the
// value pointed to can change
that would place the const qualifier before the pointer operator *. In this example, it is the pointer itself that is constant, not the int to which it points.
Our second reason has to do with a syntactical substitution principle that is very common when dealing with templates. Consider the following two type definitions [1]:
[1] Note that in C++ a type definition defines a "type alias" rather than a new type. For example:
typedef int Length; // define Length as an alias for int
int i = 42;
Lengthl = 88;
i = l; // OK
l = i; // OK
typedef char* CHARS;
typedef CHARS const CPTR; // constant pointer to chars
The meaning of the second declaration is preserved when we textually replace CHARS with what it stands for:
typedef char* const CPTR; // constant pointer to chars
However, if we write const before the type it qualifies, this principle doesn't apply. Indeed, consider the alternative to our first two type definitions presented earlier:
typedef char* CHARS;
typedef const CHARS CPTR; // constant pointer to chars
Textually replacing CHARS results in a type with a different meaning:
typedef const char* CPTR; // pointer to constant chars
The same observation applies to the volatile specifier, of course.
Regarding whitespaces, we decided to put the space between the ampersand and the parameter name:
void foo (int const& x);
By doing this, we emphasize the separation between the parameter type and the parameter name. This is admittedly more confusing for declarations such as
char* a, b;
where, according to the rules inherited from C, a is a pointer but b is an ordinary char. To avoid such confusion, we simply avoid declaring multiple entities in this way.
BYTE Ch; // Declare a variable of type BYTE.
PBYTE pbCh; // Declare a pointer to a BYTE
// variable.
The preceding example shows uniform declaration syntax for the fundamental type unsigned char and its derivative type unsigned char *. The typedef construct is also helpful in simplifying declarations. A typedef declaration defines a synonym, not a new, independent type. The following example declares a type name (PVFN) representing a pointer to a function that returns type void. The advantage of this declaration is that, later in the program, an array of these pointers is declared very simply.
// type_names.cpp
// Prototype two functions.
void func1(){};
void func2(){};
// Define PVFN to represent a pointer to a function that
// returns type void.
typedef void (*PVFN)();
int main()
{
// Declare an array of pointers to functions.
PVFN pvfn[] = { func1, func2 };