C + + header file Duplicate reference problem

Source: Internet
Author: User
Tags class definition

Intro----The pit that was encountered before writing C + +

Before because Java is really good, C + + engineering code almost don't touch, really write up when there will always be some small bug, here is a summary of one of them
A.h

#include "b.h"class a{  public: a();          ~a();}

A.cpp

#incldue "a.h"a::a(){  ....};a::~a(){  ....};

B.h

#include "a.h"class b{  public: b();          ~b();}

B.cpp

#incldue "b.h"b::b(){  ....};b::~b(){  ....};

Assuming that there are header files of the two classes above, I need to call each other on Class A, if the operation as described above will definitely fall into the duplicate inclusion problem of the header file. The correct practice should be included in the. cpp file, respectively. For reasons, write them down.

Header and source files in C + +

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 referred to as the C + + header file, which is also the source code for C + +.

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.

What is a header file

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.

What should be written in the header file

The purpose 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.

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.

Summarize

In the preprocessing phase, the preprocessor sees the # include "filename" to read this file, such as it compiles a.cpp, see # include "A.h", it reads the contents of A.H. If you repeat nesting inside a header file as before, the result is a. cpp file in # include The import of the A.h file contains b.h this time to read the contents of the B.h. In B.h, because it also refers to the A.H, it creates two definitions of the variables and methods within a. Compiler error is a matter of course. In fact, the knowledge of the compiler principle is also known to maintain a table within the compile phase. The error at this point is to define the variables in the table two times.

C + + header file Duplicate reference problem

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.