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" (separatecompilation). 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 "Voida ();". 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:
/* Math.cpp */
Double F1 ()
{
Do something here ....
Return
}
Double F2 (double A)
{
Do something here ...
Return a * A;
}
/* End of Math.cpp */
and put the declaration of "These" functions in a header file math.h:
/* MATH.H */
Double F1 ();
Double F2 (double);
/* End of MATH.H */
In another file main.cpp, I want to call these two functions, then just need to include the head file:
/* Main.cpp */
#include "math.h"
Main ()
{
int number1 = F1 ();
int number2 = F2 (number1);
}
/* End of Main.cpp */
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 has to be found in the compiler (for example, with main.cpp in a directory) Main.cpp and math.cpp can be compiled separately, generate MAIN.O and MATH.O, and then the two target files to link, 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:
/* ~main.cpp */
Double F1 ();
Double F2 (double);
Main ()
{
int number1 = F1 ();
int number2 = F2 (number1);
}
/* End of ~main.cpp */
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 an inta, or a sentence such as void F () {}, the compiler will immediately error if the header file is contained in two or more. cpp files. (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.
The difference between a C + + header file and a source file
how the source file relates the header file according to # include
1, the system comes with a header file enclosed in angle brackets, so the compiler will look in the System files directory.
2, user-defined files are enclosed in double quotes, and the compiler will first look in the user directory and thenC + +The installation directory (such as VC can specify and modify the library file lookup path,UnixAndLinuxCan be set in the environment variable) and finally found in the system file.
#include "xxx.h" (I always Thought "" "and <> is not the same, but Tinyxml.h is a non-system file, so use" ")
Ii. How to associate a source file with a header file
The problem is actually that the known header file "A.h" declares a series of functions, which are implemented in "B.cpp", so if I want to use the functions declared in "A.h" in "C.cpp" in "B.cpp", it is usually used in "c.cpp". Include "A.h", then C.cpp is how to find the b.cpp in the implementation?
In fact, there is no direct relationship between the. cpp and. h file names, and many compilers can accept other extensions. For example, I now see the source code of our company, the. cpp file is replaced by the. cc file.
In Turbo C, the command line is compiled with the name of the file, and the default is. cpp and. h, but can also be customized to. xxx and so on.
Rectification Teacher's "C Programmingis mentioned in the book, "file contains processing" for the # include command when the compiler is preprocessing: Copy the entire contents of file2.c to #include“file2.c "place. This also explains why many compilers do not care what the suffix of this file is----because the # include preprocessing is a "copy and insert Code" work.
Compile, and do not look for the function in the B.cpp file implementation, only when the link to do this work. We're in B.cpp or C.cpp #include"A.h" is actually the introduction of the relevant declaration, so that the compilation can pass, the program does not care about where the implementation is, how it is implemented. The source file is compiled into a target file (. o or. obj file), and these functions and variables are treated as symbols in the destination file. InLink, you need to indicate in makefile which. o or. obj file (here is the. o or. obj file generated by b.cpp), at which point the connector will go to the. O or. obj file to find the functions implemented in B.cpp, and thenBuildToMakefileThe one specified in the executable can be executed in the file.
Under UNIX, you can even include a header file in the source file, justMakefilecan be named (but this greatly reduces the readability of the program, is a bad habit oh ^_^). InVCIn a bunch of situations where you don't have to write your ownMakefile, you only need to include the required files in theProject, VC will automatically help you to write the makefile well.
UsuallyC + + compilerFind the required symbol in each. o or. obj file, instead of just looking in a file or finding one. Therefore, if you implement the same function in several different files, or if you define the same global variable, the link will prompt "redefined”。
to the full extent of the complaint:
The. h file can contain:
Declaration of class member data, but cannot be assigned a value
Class static data members are defined and assigned, but not recommended, just a declaration is good.
Declaration of a member function of a class
Declaration of non-class member functions
Definition of constants: such as: Constint a=5;
Definition of static function
Definition of an inline function of a class
Cannot contain:
1. Declaration of all non-static variables (not data members of the class)
2. The default namespace declaration is not placed in the header file, using namespace Std; and so on. CPP, using std::string in. h files
Original link: http://blog.csdn.net/yue34257667/article/details/45500811
Understanding the role of header and source files in C + + "Go"