Why c ++: What is the difference between the source file and the header file?

Source: Internet
Author: User
Tags see definition
1.1. What are the differences between source code files and header files?

C ++ source code files are divided into two types: header files and source code files ). Header files are used to store object declarations such as type definitions, function declarations, and global variable declarations as external interfaces. source program files are used to store type implementations, function bodies, and global variable definitions. For commercial C ++ libraries, the header files are generally published along with the binary library files, while the source code is retained.

In general, the header file uses. h or. HPP as the extension, while the implementation file uses. cpp or. cc as the extension. Header files are generally not directly compiled. A source file represents a "compilation unit ". When compiling a source file, if the referenced type, function, or other entities are not in this compilation unit, you can introduce the entities implemented in other compilation units to this compilation unit by referencing the header file.

In essence, these source code files are pure text files. You can use any text compiler to edit source code. There is no essential difference, these headers and implementation file extensions are just a habit. The header files of the C ++ standard library do not use extensions, such as string, iostream, and cstdio. Similar to source files, you can use. INL or. cplusplus as the file extension. In fact, in some C ++ projects. INL is used as the extension of the source code file, saving inline functions, directly included in the source file, such as ACE (the adaptive communication environment, http://www.cse.wustl.edu /~ Schmidt/ace.html. By default, GCC supports C ++ source file extensions. CC ,. CP ,. CPP ,. cxx ,. c ++ ,. CPP ,. C (note that the last two items are in uppercase and the file names in Unix/Linux are case sensitive ). For example, in GCC, You can compile a C ++ program with the extension. cplusplus:
G ++-x C ++ demo. cplusplus
Although the file name has no effect on the program. CPP and. CC extensions are supported by the compiler by default. With these extensions, you do not need to manually add compilation options to support your extensions, such as the-x option in GCC.

In fact, the header file with what is the extension does not have any impact, because no one will directly compile the header file, because the header file is only declared and not defined, but in the actual compilation process, # The header file used by the include pre-compilation command is directly inserted into the source code file and then compiled. This is no different from directly copying the content of the header file to the # include row location, in this way, it is easy to understand where # include can appear in the file. Obviously, it is inappropriate to put it in the definition of a function body or class.

1.1.1. What is the difference between definition and declaration?

Generally, the definition should be placed in the source code file, and the declaration should be placed in the header file. The specific content should be put in the source code file and the content should be put in the header file. You need to clearly understand what is definition and what is declaration.

1.1.1.1. Definition and declaration of Classes

The class definition defines the complete structure of the class, including the member functions and member variables, such as the routine [2-1].

// Routine 2-1: Class Definition

Class Point

{

PRIVATE:

Int X _;

Int Y _;

Public:

Point (int x, int y );

Int X (void) const;

Int y (void) const;

};

The class declaration only indicates the existence of this type, but does not define what type it is, such as the routine [2-2].

// Routine 2-2: Class Declaration

Class Point;

Class description and implementation can be placed in the header file, because the upper-Layer Code must use the Point class to know that the class has been defined in the current project. But should I use the definition or declaration? Definitions can be used wherever declarations are available. However, too many definitions can prolong the project Compilation Time and speed down compilation. For details, see (@ See definition series, item 34 ).

Another case is that the declaration must be used, that is, when two classes reference each other in the definition, such as the routine [2-3]. Of course, this situation rarely occurs. In most cases, you can try to avoid it by modifying the design. This method can only be used in unavoidable situations.

// Example 2-3: cross-reference of Class Definition

Class B;

Class A {public: B & getb (void) const ;}

Class B {public: A * createa (void) const ;}

The class definition only gives the data (member variables) and interfaces (member functions) contained in the class, but does not provide implementation. The implementation of the program should be placed in the original code file. As the point class in routine [2-1] is defined in the point. HPP header file, the content of the corresponding source code file point. cpp is shown in routine [2-4.

// Example 2-4: Implementation of member functions

Point: Point (int x, inty)

: X _ (x), Y _ (y)

{

}

Int point: X (void) const

{

Return X _;

}

Int point: Y (void) const

{

Return Y _;

}

Of course, the implementation of the class member functions can also be put into the header file, but the inline modifier will be added to these functions by default during compilation, as an inline function. Simple read-value functions such as point: X and pointy are suitable for storing them in header files as inline functions. For details, see [?? Inline.

1.1.1.2. Definition and declaration of functions

The function declaration only describes the external interface of the function, but does not include the implementation function body of the function, as shown in the routine [2-5.

// Routine 2-5: function declaration

Int splitstring (vector & Fields

, Const string & Str

, Const string & delimiter );

The function definition is all parts including the function declaration and function body. As shown in the routine [2-6], a function for splitting strings is provided, although the efficiency is not high, but it is indeed a function that can work.

// Routine 2-6: Function Definition

Int splitstring (vector & Fields

, Const string & Str

, Const string & delimiters)

{

String tmpstr = STR;

Fields. Clear ();

String: size_type pos1, pos2;

For (;;){

Pos1 = pos2 = 0;

If (pos1 = tmpstr. find_first_not_of (delimiters, pos2 ))

= String: NPOs)

Break;

If (pos2 = tmpstr. find_first_of (delimiters, pos1 ))

! = String: NPOs ){

Fields. push_back (tmpstr. substr (pos1, pos2-pos1 ));

} Else {

Fields. push_back (tmpstr. substr (pos1 ));

Break;

}

Tmpstr. Erase (0, pos2 );

}

Return fields. Size ();

}

A function declaration can be placed before any function that calls it. Before calling a function, you must define or declare the called function before calling the function. The function can only be defined once. If the caller and the called are not in the same compilation unit, you can only add the function declaration before the caller. The function can be defined only once, and the function declaration can be unlimited (theoretically). This is also the role of the header file. It puts a batch of function declarations into a header file, reference this header file wherever these function declarations are needed for maintenance.

Before the function declaration, an optional extern modifier indicates that the function is defined in other compilation units or in the function library. Although it is not necessary for function declaration, it can be used to directly declare functions implemented in other compilation units in a source file to improve readability. Assume that the function splitstring in the routine [2-6] is defined in strutil. in the CPP file, and in the strutil. CPP also defines many string-related functions, other. CPP only uses strutil. the splitstring function in CPP. To improve compilation speed, you can declare the function directly in other. cpp, instead of directly referencing the header file. In this case, it is best to use the extern mark to make the program more readable.

1.1.1.3. Definition and declaration of Variables

The declaration of a variable carries the extern identifier and cannot be initialized. The definition of a variable does not have the extern identifier and can be initialized during definition, as shown in [2-7] of the routine.

// Routine 2-7: definition and declaration of Variables

// Statement

Extern int global_int;

Extern STD: String global_string;

// Define

Int global_int = 128;

STD: String global_string = "Global string ";

In form, unlike the declaration of a function, the extern in the declaration of a variable is required. Without the extern modifier, the compiler will treat it as a definition. To distinguish declaration from variable, the compiler needs to allocate memory space for variable definition, but does not need to allocate memory space for variable declaration.

1.1.1.4. Summary

Theoretically, the difference between a declaration and a definition is that the definition describes the internal content, and the declaration does not disclose the internal content, but only indicates the external interface. For example, the class definition includes the declaration of internal members, while the class declaration does not contain any internal details of the class. The function definition includes the function body, function declaration only includes the function signature. variable definitions can contain initialization, while variable declarations cannot contain initialization.

The statement can be repeated, but the definition cannot be repeated.

Separation of declaration and definition seems inconvenient, but it can separate implementation from interfaces. In addition, the header file itself is a good interface Description document with good self-description, in addition, the current intelligent integrated development environment (IDE) is more convenient than reading other types of documents. C # added the concept of "partial Method" in 3.0. Its role is similar to that of header files, which also demonstrates the advantages of header files.

In terms of engineering, the file name of the header file should be the same as the corresponding source file name for easy maintenance. If the header file contains definitions or declarations from multiple source files, the code in the header file should be arranged by the source file group, and the source files of each group should be noted through annotations. When there are many files in a project, the source file and the header file should be stored in separate directories. The general header file is stored in the include or INC directory, and the source file is stored in the source or src directory. Based on experience, when the number of files in a project exceeds 30, the source files and header files should be stored separately. When there are few files, you can directly put them in the same directory.

1.1.2. Why does # ifndef/# define/# endif pre-compiled command exist in the header file?

Although the Declaration of functions and variables can be repeated, the same declaration does not affect the running of the program multiple times, But it increases the Compilation Time, so repeated reference of header files will waste compilation time; in addition, when the header file contains some definitions such as class definition, template definition, and enumeration definition, these definitions cannot be repeated and some measures must be taken to prevent repeated references, this is why # ifndef/# define/# endif is often seen in the header file. The general format is shown in the routine [2-8.

// Routine [2-8]

# Ifndef headerfile_h

# Define headerfile_h

// Place defines and declarations here

# Endif

Some compilers also support some compiler commands to prevent repeated references, such as Visual C ++.

# Pragma once

Command to avoid reading disk files, which is more efficient than # ifndef/endif.

1.1.3. # include What is the difference with # include "filepath "?

In C ++, there are two methods to reference header files:

// Form 1

# Include

// Form 2

# Include "filename"

In fact, the C ++ standard does not determine the order of the two methods for searching the file filepath, but is determined by the implementation of the compiler, the difference is that if the compiler fails to search for the file filepath in the order defined in the second form or this method is not supported, it will be replaced with the first order and then searched.

In fact, the first method is to search the system directory of the compiler first, while the second method is to search the directory where the compiled header file is located for the current directory, if the search fails, search in the system header file. These two methods are essentially no different, but when we use our own program file and system header file to name it again, the latter will first find our header file instead of the system. However, in any case, it is not a good habit to rename the system header file. If you are not careful, it may cause unnecessary trouble. When we compile the library ourselves, we 'd better put it into a directory, do not add this directory directly to the header file search path of the compiler (such as gcc-I, Visual C ++/I options, etc, in fact, the compilers on Unix/Linux platforms generally use the-I option). Instead, they are added to the upper-level directory, and the directory name is included when the header file is referenced in our source file, this is not easy to cause conflicts.

For example, we have created a library named mylib, and one of the header files is strutil. HPP, we can create a/home/user/project/src/mylib directory, and then put strutil. put HPP in, and then add/home/user/project/src to the compilation options:

Gcc-I/home/user/project/src

In this way, we can reference the strutil. HPP file in our source program as follows:

# Include "mylib/strutil. HPP"

By referencing the header file with the displayed directory name, it is not easy to confuse our own header file with the system header file.

Of course, from the code logic, we also have another solution to solve the conflict, that is, the namespace. For details, see section [?]. Section.

1.1.4. # include And # include What is the difference?

The two differences are obvious, because they reference not the same head file, but their role is not obvious, and there is no difference in functionality. Without the extension, a series of header files prefixed with the letter C only introduce the corresponding C standard header files to the STD namespace and place the standard library into the STD namespace, in addition, such as cstdlib and cmath.

If the latter is referenced, use

Using namespace STD;

To introduce the STD namespace, or display the standard library function called by the domain identifier, such

STD: printf ("hello from noock ");

It is recommended that the latter be used in C ++ projects, especially in large and medium-sized projects, to avoid conflicts of identifiers as much as possible.

Related Article

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.