C ++ BASICS (2)

Source: Internet
Author: User

InC ++Class, that is, the class of the custom type (referred to as the class), which has no difference with the structure at all, but is explained in the next article ), the reason for providing a class is actually because C ++ is extended from C, and the class is a very important concept proposed by C ++, the keyword struct is reserved only for compatibility with the C language. Next to the previous article>

Description

I have already explained the meaning of declaration. Here, due to the new definition syntax of the member function definition rules, the meaning of declaration must be reconsidered. Note that you can place the definition of a function before the definition of the main function, and you do not need to declare that function. If you define a variable, you do not need to declare that variable. This means that the definition statement has the declaration function, but the Definition Statement of the above member function does not have the declaration function. The following describes the true meaning of the Declaration.

Declaration is a statement that requires the compiler to generate ing elements. The so-called ing element refers to the variables and functions described earlier. There are only three columns or three fields ): the type column, name column, and address bar member variable type column place the offset value ). That is, the compiler generates a ing element every time it sees the declaration statement, and leaves the corresponding address bar blank, and then leaves some information to tell the connector -- this. the file generated after the obj file compiler compiles the source file. obj file) requires some symbols, find these symbols and then modify and improve this. obj file.

In retrospect, the symbol is a string used for communication between the compiler and the connector. Note that there is no type for the symbol, because the connector is only responsible for finding and perfecting the symbol because the address bar of some ing elements is still empty.) The intermediate file is for VC. obj file), no syntax analysis, there is no type.

The definition requires the compiler to fill in the address bar that was previously declared not written. That is to say, the address corresponding to a variable is only known when it is defined. Therefore, the actual allocation of memory on the stack is completed by the definition of variables, so declared variables do not allocate memory. Note that the definition is the address required to generate the ing element. Therefore, the definition shows the address of the ing element it generates, if no ing element exists in the ing table of the compiler, that is, the variable table or function table used to record the ing element in the compiler, that is, if no declaration has been made for the corresponding element, the compiler will report an error.

But I only wrote one variable or Function Definition Statement before. Is it still normal and there is no error? Actually, it is very simple. You only need to regard the Declaration and definition as a statement, except that the information provided to the compiler is different.

For example:

 
 
  1. Void ABC (float );
  2. And
  3. Void ABC (float ){}

The compiler looks at them the same way. The former provides the function type and type name, so the compiler only fills in the ing element name and type columns. The compiler cannot enter the address bar because only ";" is followed and no code for this function ing is provided. The latter provides a composite statement with the function name, type, and ing Code null). Therefore, the compiler obtains all the information to be filled in and then fills in the information in the three columns, the result shows that the definition statement completes the declaration function.

For variables, such as long ;. Same as above, the type and name are provided here, so the compiler fills in the two columns: type and name. However, the variable corresponds to the first address of a memory block on the stack, this first address cannot be displayed in the Code. The previous function writes a compound statement after the function declaration to show the address of the code corresponding to the corresponding function ), it must be obtained through computation within the compiler. Therefore, it is hard to specify that the above writing is counted as the definition of a variable, and the declaration of a variable must be preceded by extern. That is, the compiler will perform internal computation to get the corresponding address and fill in all the information of the ing element.

It is inevitable that the above seems to be confused because of the emergence of custom types. Consider the definition of member variables, such

 
 
  1. struct ABC { long a, b; double c; }; 

The preceding examples show the types -- long ABC:, long ABC:, and double ABC:; and the names -- ABC: a, ABC: B, and ABC: c; given the address (offset) -- 0, 4, and 8. Because it is a structure-defined type, the offset of each member variable can be obtained through this statement. The above three pieces of information can be filled in all the information of the ing element, so the above can be counted as a Definition Statement. For member functions, see the following:

 
 
  1. struct ABC { void AB( float ); }; 

The preceding example shows the type -- void (ABC:) (float); The name is -- ABC: AB. However, because no address is provided, you cannot fill in all the information of the ing element. Therefore, the above is the declaration of the member function ABC: AB. As mentioned above, you only need to give the address, and you don't have to worry about whether it is a definition or declaration, so you can do this:

 
 
  1. struct ABC { void AB( float ){} }; 

The type and name are given above, and the address is given at the same time. Therefore, all information of the ing element can be filled in completely, which is the definition. The usage above has its own particularity, which is described later. Note: If the ABC: AB Definition Statement is followed by the following statement, it will be incorrect:

 
 
  1. struct ABC { void AB( float ){} };  
  2. void ABC::AB( float ) {} 

The above error will be reported for a simple reason, because the latter is only defined, it only provides the ABC: AB address information, but the address bar in the ing element has already been filled in, the compiler will repeat the definition. Let's look at the definition of the member function separately. It provides the void type (ABC:) (float), the name ABC: AB, and the address, but why does it only provide the address?

First, the name ABC: AB does not comply with the identifier rules, and the type modifier ABC: Must be added through the type definition character, this has been described multiple times before. Therefore, the above information is: given an address, which is the address of the ing element of the type void (ABC:) (float) and ABC: AB.

The result compiler looks for such a ing element. If yes, enter the corresponding address bar. Otherwise, an error is reported, indicating that only one void ABC: AB (float) {} is incorrect, you must first declare the corresponding ing element through the type definition character. That is, the definition mentioned above only fills the address bar and does not generate ing elements.

Role of statement

The role of the definition is obvious, and the meaningful ing name is for the address). But what is the purpose of the declaration? It only generates the name of the type pair. Why do we need the name of the type pair? It just tells the compiler not to make an error saying that the variable or function is not defined? Everything has its own meaning. Let's take a look at the following code.

 
 
  1. extern"C" long ABC( long a, long b );  
  2. void main(){ long c = ABC( 10, 20 ); } 

Assume that the above Code is written in a. cpp and the file a. obj is compiled and generated. However, according to the previous instructions, the connection will be incorrect because the symbol _ ABC cannot be found. Because the address bar corresponding to name_abc is still empty. Add a new source file B. cpp to the project where a. cpp is located in VC, and write the following code.

 
 
  1. extern"C" float ABC( float a ){ return a; } 

Compile and connect. Now there is no problem, but I believe you have seen the problem. -- the declaration of function ABC does not match the defined type, but the connection is successful?

Note that the preceding connection description indicates that there is no connection type, just a symbol. Use extern "C" to make. obj requires the _ ABC symbol, while B. cpp provides the _ ABC symbol, and the rest is that the connector splits B. put the address of _ ABC in obj to. obj to improve. obj, connect to. obj and B. obj.

In the above result, the compiler can still generate code even if there is no address to implement the function of the function operator-function call. This is because the type and name must be given at the same time during declaration, because the type tells the compiler how to generate code to implement this operator when an operator involves a ing element.

That is to say, the numeric multiplication of two char Types is different from the code generated by the multiplication of two long types. The function calling code of long ABC (long); is different from that of void ABC (float. That is, the different numeric types used by operators will lead to different code generated by the compiler.

So why should we put the ABC definition in B. cpp? Because the compilation between source files is independent, if it is placed in a. cpp, the compiler will find that such a ing element already exists, but the type does not match, and an error will be reported. Put it in B. cpp, so that the connector can improve a. obj. Then there will be no type, just the symbol. Continue.

 
 
  1. struct ABC { long a, b; void AB( long tem1, long tem2 ); void ABCD(); };  
  2. void main(){ ABC a; a.AB( 10, 20 ); } 

As mentioned above, although ABC: AB is not defined here, it can still be compiled successfully without any problems. Assume that the above Code is in a. cpp, add B. cpp, and write the following code in it.

 
 
  1. struct ABC { float b, a; void AB( long tem1, long tem2 ); long ABCD( float ); };  
  2. void ABC::AB( long tem1, long tem2 ){ a = tem1; b = tem2; } 

The function ABC: AB is defined here. As mentioned earlier, the function definition here is only defined, therefore, you must write the type definition character "{}" before it to let the compiler generate a ing element. However, we should note that the bitwise of the member variables is replaced here, so that B maps 0 and a maps 4, and the types of a and B are changed to float, and. the definition in cpp is quite different. But there is no problem, the compilation connection is successful,

 
 
  1. a.AB( 10,20 ); 

A. a Is 0X41A00000,. B is 0X41200000, and * (float *) &. a is 20, * (flaot *) &. B is 10.

Why? This is because the compiler only follows type matching in the source file currently compiled, and all the ing elements generated by compiling other source files are invalid when compiling another source file. Therefore, the Declaration binds the type and name, and the name represents the number of the address type associated with the type, the compilation and generation of all operators operating on this number in the subsequent code will be affected by the type of this number. That is, Declaration tells the compiler how to generate code. It is not only a syntax statement that describes variables or functions, but is indispensable.

Note that the ABC: ABCD member functions in the preceding two files have different declarations, and the entire project is called. cpp and B. in cpp) there is no definition of ABC: ABCD, but the connection can still be compiled successfully, because the Declaration does not tell the compiler what is already there, but how to generate code.

Header file

As described above, if there is a custom type ABC. cpp, B. cpp and c. to use it in cpp, it must be in. cpp, B. cpp and c. in cpp, use the "{}" type definition character before ABC to re-define the custom type. If you accidentally write different definitions in a. cpp and B. cpp as shown in the preceding figure, a difficult-to-find error will occur. Therefore, C ++ provides a pre-compiled command to help you.

Precompiled commands are the commands executed before compilation. They are interpreted and executed by the Pre-compiler. The pre-compiler is another program. Generally, the compiler vendors merge the program into the C ++ compiler and only provide one program.

In this example, the precompiled instruction contains the instruction -- # include, in the format of # include <File Name>. Note that precompiled commands must occupy a single line, and <File Name> is a file name enclosed by double quotation marks or angle brackets,

For example, # include "abc. c", # include "C: \ abc. dsw", or # include <C: \ abc.exe>. The function is very simple, that is, to interpret the file name corresponding to the quotation marks or angle brackets in ANSI or MBCS format, and replace the content with the position of # include in sequence, for example, the following is the abc content of the file.

 
 
  1. struct ABC { long a, b; void AB( long tem1, long tem2 ); }; 

The preceding a. cpp can be changed:

 
 
  1. #include "abc"  
  2. void main() { ABC a; a.AB( 10, 20 ); } 

B. cpp can be changed:

 
 
  1. #include "abc"  
  2. void ABC::AB( long tem1, long tem2 ){ a = tem1; b = tem2; } 

At this time, it will not appear in B. in cpp, an error occurs when the definition of ABC of the custom type is written.. a Is 0X41A00000,. B is 0X41200000), and then. AB (10, 20); after execution,. a is 10,. B is 20.

Note that double quotation marks are used to enclose the file name. It indicates that when only one file name or relative path is included and the full path is not given, search for the Directory of the source file to be compiled at this time, and then search for the compiler's custom include directory, such as C: \ Program Files \ Microsoft Visual Studio. NET 2003 \ Vc7 \ include, etc.), which usually contains the header file of the SDK that comes with the compiler. If the header file is still not found, an error is reported. Note, generally, the compiler provides some options so that you can search for the specified directory in addition to the preceding directory. Different compiler settings are different and are not listed here ).

If it is enclosed by Angle brackets, it indicates that the self-defined include directory of the compiler is searched first, and then the directory where the source file is located. Why is it different? Only to prevent conflict between the file name and the file name under the compiler's include directory, because once the file is found, the subsequent directory will not be searched.

Therefore, in General C ++ code, if you want to use a custom type, all the custom type definitions are packed in two files respectively. For the above structure ABC, two files, ABC. h and ABC. cpp, where ABC. h is called the header file, while ABC. cpp is called the source file. The Declaration is put in the header file, while the definition is put in the source file, the content of ABC. h is the same as that of abc, and the content of ABC. cpp is the same as that of B. cpp.

Then, whenever the structure ABC is used in a source file in the project, ABC is included at the beginning of the source file. h, which is equivalent to bringing all the relevant declarations of the structure ABC into the compilation of that file, such as the previous. cpp declares the structure abc by including ABC at the beginning.

Why do we need to generate an ABC. cpp? If the Definition Statement of ABC: AB is also put in ABC. h, then. cpp should use ABC, c. cpp also uses ABC, so. cpp contains ABC. h. Because of the definition of ABC: AB, a symbol is generated? AB @ ABC @ QAEXJJ @ Z for VC); similarly, c. this symbol must also be generated during cpp compilation. When two identical symbols appear during the connection, the connector cannot determine which one to use and an error is returned. Therefore, ABC. cpp is defined specifically, and the definition of ABC: AB function is put into ABC. obj. In this way, only one symbol is generated and no error is reported during connection.

Note that

 
 
  1. struct ABC { void AB( float ){} }; 

If you put this in ABC. in h, because the ABC: AB function has been given in the type specifier, two identical symbols will appear in the same way, and the connection fails. To avoid this problem, C ++ requires that the function defined in the previous example is an inline function, which is directly written into the function definition in the Type Definition operator. For more information, see the next section.

Member meaning

The above describes the meaning of a member function from the perspective of syntax. If it is dizzy, it doesn't matter. Implementation doesn't mean it can't be used, what is important for programmers is the ability to use the language rather than the degree of understanding of the language, although the latter is also very important ). The following describes the member semantics.

At the beginning of this article, we propose a kind of semantics-the function of a resource, and the custom type of C ++ is added with the member operator ". the use of "and"-> "easily shows a semantic-subordination in code. For example, a. B and c. d indicate B of a and d of c respectively. To map the functions of a resource to C ++, you should map the resource to a custom type, and its functions are mapped to member functions of this custom type, for example, the monsters and players mentioned at the beginning are as follows:

 
 
  1. struct Player { float Life; float Attack; float Defend; };  
  2. struct Monster { float Life; float Attack; float Defend; void AttackPlayer( Player &pla ); };  
  3. Player player; Monster a; a.AttackPlayer( player ); 

The semantics above is very obvious. The operations executed by the Code are monster a attacking the player, and player. Life represents the player's Life. Assume that Monster: AttackPlayer is defined as follows:

 
 
  1. void Monster::AttackPlayer( Player &pla )  
  2. {  
  3. pla.Life -= Attack - pla.Defend;  

The semantics above is very obvious: the method by which a monster can attack a player is to subtract its own attack power from the defensive power of the attacked player. The semantics is very clear and the code is readable. As in the original statement:

 
 
  1. void MonsterAttackPlayer( Monster &mon, Player &pla )  
  2. {  
  3. pla.Life -= mon.Attack - pla.Defend;  

The semantics of the Code: the monster attacking player is an operation. This operation requires two resources, respectively, the monster type and the player type. This Semantics does not show what we were going to do, but another explanation of the monster's attack function. It is more suitable for the Cashier's work. For example, the cashier is responsible for collecting money. When a customer buys something at the counter, the salesperson opens a ticket and the customer receives the ticket to pay for it.

Here, the cashier needs to operate on two resources-money and documents. In this case, the money collection should be mapped to the above function rather than the member function, because in this algorithm, there is no need to map the cashier to a custom type, that is, we don't care who is responsible for the Cashier's work, but how it is done.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.