One, C + + compilation mode
Typically, in a C + + program, only two types of files ——. cpp files and. h files are included. Where. cpp files are referred to as C + + source files, and the. h file is called the C + + header file, and the source code for C + + is included.
c+ + language supports "compile separately" (separate compilation). That is, all the content of a program can be divided into different parts in different. cpp files. The things in the CPP file are relatively independent and do not need to be interoperable with other files when compiling (compile). It is only necessary to make a link to the other target file after compiling it into the target file. For example, a global function "void A () {}" is defined in file A.cpp, and this function needs to be called in file B.cpp. Even so, file a.cpp and file b.cpp do not need to know each other's existence, but can be compiled separately, compiled into the target file after the link, the entire program can be run.
How is this going to be achieved? From the point of view of writing programs, it is very simple. In file B.cpp, before calling the "void A ()" function, declare the function "void A ();". This is because the compiler generates a symbol table when compiling the B.cpp, which, like "Void A ()", does not see the defined symbol and is stored in the table. When the link is made, the compiler will look for the definition of the symbol in the other target file. Once found, the program can be successfully generated.
Note that two concepts are mentioned here, one is "definition" and one is "declaration". Simply put, "definition" is the complete description of a symbol: it is a variable or function, what type of return, what parameters are required, and so on. and "declaration" just declares the existence of this symbol, that is, to tell the compiler, this symbol is defined in other files, I use it first, you link to other places to find out what it is. When defining a symbol (a variable or a function) in C + + syntax, it is only necessary to write a prototype of the symbol when declaring it. It is important to note that a symbol can be declared multiple times throughout the program, but is only defined once. Imagine, if there are two different definitions of a symbol, who should the compiler listen to?
This mechanism brings a lot of benefits to C + + programmers, and also introduces a way to write programs. Consider, if there is a very common function "void f () {}", which is called in many. cpp files throughout the program, then we just need to define the function in one file, and declare the function in the other file. A function is good to deal with, the statement is also a sentence. However, if there are many functions, such as a large number of mathematical functions, there are hundreds of, how to do? Does it make sure that every programmer can completely write down all of the functions exactly in the form?
Ii. what is a header file
It is clear that the answer is impossible. But there is a very simple way to help programmers save the hassle of remembering so many function prototypes: we can write all of the hundreds of function statements first, put them in a file, and copy all of them into his source code when the programmer needs them.
This method is feasible, but it is too troublesome, and it seems very clumsy. As a result, the head file can play its part. The so-called header file, in fact its content is the same as in the. cpp file, is the source code of C + +. But the header file does not have to be compiled. We put all the function declarations in a header file, and when a certain. cpp source file needs them, they can be included in the. cpp file by a macro command "#include" to merge their contents into the. cpp file. When the. cpp file is compiled, the role of these included. h files is played.
For example, assuming that all mathematical functions are only two: F1 and F2, then we put their definitions in math.cpp:
Double F1 ()
{
Do something here ....
Return
}
Double F2 (double A)
{
Do something here ...
Return a * A;
}
and put the declaration of "These" functions in a header file math.h:
Double F1 ();
Double F2 (double);
In another file main.cpp, I want to call these two functions, then just need to include the head file:
#include "math.h"
Main ()
{
int number1 = F1 ();
int number2 = F2 (number1);
}
In this way, it is a complete program. It is important to note that the. h file is not written after the compiler's command, but it must be in place where the compiler can find it (such as with main.cpp in a directory). Main.cpp and Math.cpp can be compiled separately, generate MAIN.O and MATH.O, and then link the two target files, the program can be run.
Third, #include
#include is a macro command from the C language, which works before the compiler compiles, at the time of precompilation. #include的作用是把它后面所写的那个文件的内容, complete the whole place, the word does not change to include in the current file. It is worth mentioning that it has no other function or function, and its function is to replace every place where it appears, replacing it with the content of the file written behind it. Simple text substitution, nothing else. Therefore, the first sentence in the main.cpp file (#include "math.h") is replaced with the contents of the Math.h file before compiling. That is, when the compilation process is about to begin, the content of main.cpp has changed:
Double F1 ();
Double F2 (double);
Main ()
{
int number1 = F1 ();
int number2 = F2 (number1);
}
Not much, just good. In the same way, if we have more than main.cpp, there are many more. cpp files are also used in the F1 and F2 functions, then they all just need to write in the two functions before the use of "math.h" on the line.
Iv. what should be written in the header file
From the above discussion, we can understand that the role of the header file is to be included in the other. cpp. They are not themselves involved in compiling, but in fact, their content is compiled in multiple. cpp files. With the "Define only once" rule, it is easy to conclude that the header file should only have declarations of variables and functions, not their definitions. Because the contents of a header file are actually introduced into several different. cpp files, they are all compiled. It's okay to put a statement, if you put a definition, it's equivalent to having a definition of a symbol (variable or function) in multiple files, even though the definitions are the same, but for the compiler, it's not legal.
So, one thing to keep in mind is that in. h header files, only declarations of variables or functions can exist, not definitions. That is, you can only write in the header file such as: extern int A; and void f (); These are the statements. If you write a sentence of int a, or void F () {}, then once the header file is contained by two or more than two. cpp files, the compiler will immediately error. (for extern, as discussed earlier, the distinction between definitions and declarations is no longer discussed here.) )
However, there are three exceptions to this rule.
One, the definition of the const object can be written in the header file. Because the global Const object defaults to no extern declaration, it is only valid in the current file. Write such an object into the header file, even if it is contained in many other. cpp files, this object is only valid in the file containing it, and is not visible to other files, so it does not result in multiple definitions. At the same time, because the objects in these. cpp files are included in a header file, this ensures that the value of this const object in these. cpp files is the same, which can be described as double benefit. Similarly, the definition of a static object can be put into a header file.
The definition of inline function (inline) can be written in the header file. Because the inline function requires the compiler to expand inline as it is encountered in its definition, rather than as a normal function that declares the relink (the inline function does not link), the compiler needs to see the full definition of the inline function at compile time. If the inline function can only be defined once as a normal function, this is a difficult thing to do. Because it's OK in a file, I can write the definition of the inline function at the very beginning, so that you can see the definition when you use it later, but what if I use the function in other files? This is pretty much a good solution, so C + + stipulates that inline functions can be defined more than once in a program, as long as the inline function appears only once in a. cpp file, and in all. cpp files, the inline function is defined in the same way that it can be compiled. Obviously, it is wise to put the definition of an inline function into a header file.
Third, the header file can be written in the definition of classes (class). Because when creating an object of a class in a program, the compiler can only know how the class's objects should be laid out when the definition of the class is fully visible, so the requirement for the definition of the class is essentially the same as the inline function. Therefore, it is a good practice to put the definition of a class into a header file and use it to include this header file in the. cpp file of this class. In this case, it is worth mentioning that the definition of a class contains data members and function members. Data members are not defined until a specific object is created (allocating space), but function members need to be defined at the outset, which is what we typically call the implementation of the class. In general, we do this by placing the definition of the class in the header file, and putting the implementation code of the function member in a. cpp file. It's OK, and it's a good idea. However, there is another way. That is to write the implementation code of the function member directly into the class definition. In a C + + class, if a function member is defined in the definition body of a class, the compiler will consider the function inline. Therefore, it is legal to write the definition of a function member into the class definition body and put it in the header file together. Note that it is not legal to write the definition of a function member in the header file of a class definition, but not in the class definition, because the function member is not inline at this time. Once the header file is contained by two or more. cpp files, the function member is redefined.
V. Protection measures in the header document
Consider that if the header file contains only declaration statements, it is not a problem to have multiple occurrences of the same. cpp file-Because the declaration statement is not restricted. However, the three exceptions in the header file discussed above are also a useful use for header files. Then, once one of the above three exceptions appears in a header file, it will be a lot more problematic if it is included in more than one. cpp. Because the syntax elements in these three exceptions are "can be defined in more than one source file", "only one occurrence in one source file" is allowed. Imagine that if A.H contains the definition of Class A, b.h contains the definition of Class B, because the definition of Class B relies on Class A, so B.h also includes a.h. Now there is a source file, it uses both Class A and Class B, so the programmer in this source file both the a.h included in the, but also the b.h included in the. At this point, the problem is: the definition of Class A has appeared in this source file two times! So the entire program cannot be compiled. You might think this is a programmer's fault-he should know that B.h contains a.h--but in fact he should not know.
Using the #define MATE condition compilation can be a good solution to this problem. In a header file, a name is defined by a # define, and the conditional compilation #ifndef ... #endif使得编译器可以根据这个名字是否被定义, and then decide whether you want to continue compiling the subsequent contents of the header. This method is simple, but you must remember to write the header file.
How C + + header files work