In the C ++ programming language, there are many functional implementation methods that are different from other languages, especially compared with the C language, its application methods are more flexible and convenient. Here we will introduce in detail the methods related to the C ++ declaration syntax.
A Declaration declares an entity for each declaration sub-object. At the same time, a name is given for that object, and the storage class, type, and other features provided by the specifier are implicitly given. The specifiers and enames determine whether the name is an object, array, pointer, reference, or function. For example,
Declare x as an integer pointer, and f returns an integer for a function. It is the declaration sub-x and f () that make the types x and f different.
- int *x, f();
- declarator: [ * [ const ] | & ]... direct-declarator
- direct-declarator: declarator-id | ( declarator ) |
- direct-declarator ( parameter-declaration-list ) |
- direct-declarator [ constant-expression ]
- A declarator-id is an identifier, possibly qualified:
- declarator-id: [ nested-name-specifier ] identifier
- nested-name-specifier: { class-or-namespace-name ::}...
If the Declaration sub-is a direct-declaration sub that contains only one declarator-id, this indicates that this identifier has an implicit attribute of decl-specifiers without further modification. For example, in the C ++ declaration syntax below
Int n;
The Declaration sub-is n, which is a declarator-id that only contains direct-declarator. Therefore, according to the meaning, the n type is an integer.
If the declaration is in another form, you can determine the type of the identifier according to the following method: first, assume that T is the implicit type of decl-specifiers, and ignore non-type attributes such as friend or static, assume that D is the declaration sub. Repeat the following steps until you export D to A declarator-id. T is the type you are looking:
- Basic Content of C ++ namespace
- C ++ breakpoint invalid Solution
- C ++ basic function code example
- Differences between C ++ Operator Overloading and different methods
- Detailed introduction to the C ++ file Stream Application Method
1. If D is like (D1), replace D with D1.
2. if D is like * D1 or * const D1, replace T with "pointer, it points to T" or "constant pointer, it points to T" based on whether const exists, then replace D with D1.
3. if the D-form is D1 (parameter-declaration-list), replace T with the parameter defined by parameter-declaration-list, and then replace D with D1.
4. If D is like D1 [constant-expression], replace T with the number of elements in the T array given by the constant-expression, and then replace D with D1.
5. Finally, if the declaration sub-shape is like & D, replace T with "T reference", and then replace D with D1.
As an example, consider the following C ++ declaration syntax
Int * f ();
First, T and D are int and * f () respectively, so D is like * D1, where D1 is f ().
You may think D can be like D1 () or * D1. However, if D is like D1 (), D1 will have to be * f, d1 will be a direct-declarator because the syntax at the beginning of this section Note 1 stipulates that only direct-declarator is preceded ()). But if we look at the definition Note 2 of direct-declarator, it is obvious that it cannot contain *. Therefore, D can only be * f (), which is like * D1, where D is f ().
Since we have determined that D1 is f (), we know that we must replace T with "pointer, it points to T", that is, "pointer, pointing to integer", and f () at the same time () replace D.
So far, we have not resolved D to declarator-id, so we must repeat this process. In this case, D1 can only be f. Therefore, we replace T with the "Return T function", which is a "Return integer pointer without Parameters" function, and then replace D with f.
At this time, D is declarator-id, so the derivation ends. We have determined the statement
Int * f ();
The declared f type is "a function that returns an integer pointer without a parameter ". In another example, declare
Int * p, q;
Has two sub-statements: * p and q. For each sub-statement, T is an int. For the first sub-declaration, D is * p, so T becomes "pointer, it points to integer," and D is p. Declare p type as "pointer, it points to integer ".
We separately analyze the second declaration sub, T or int, and D is q. It is obvious that q is an integer.
Finally, let's analyze the strange example in section 10. 1.2/173:
Double (* get_analysis_ptr () (const vector <Student_info> &);
The C ++ declaration syntax process can be analyzed in the following five steps:
1. T: double D: (* get_analysis_ptr () (const vector <Student_info> &)
2. T: returns the double function D with the const vector <Student_info> & parameter (* get_analysis_ptr ())
3. T: function returning double... (as shown in the previous figure) D: * get_analysis_ptr ()
4. T: pointer, which points to a function D that returns double...: get_analysis_ptr ()
5. T: a function that returns a function pointer pointing to a function D that returns double...: get_analysis_ptr
Get_analysis_ptr is a function that returns a function pointer pointing to a function that returns a double value with the const vector <Student_info> & parameter. We will show how to expand const vector <Student_info> & as an exercise. Fortunately, the C ++ declaration syntax is so confusing; most of them look like
Declarator: declarator-id (parameter-declaration-list)
So far, the most common problem is the function that returns the function pointer.