[C + + advanced path] three methods for C + + to prevent header files from being repeatedly introduced!

Time:2022-5-2

Previously, we introduced in detail how to use macro definition (#ifndef / #define / #endif) in C language to effectively avoid repeated #include of header files. This method is also commonly used in C + + multi file programming.

For example, the following is a C + + project with school H and student H these two header files and main CPP source files, which contain the following codes:

//student.h

class Student {

    //……

};

//school.h

#include “student.h”

class School {

    //……

private:

    Student stu[50];

};

//main.cpp

#include “student.h”

#include “school.h”

int main() {

    //……

    return 0;

}

Running this project will find that the compiler reports a “student type redefinition” error. This is because in school Once in the file “include. Student # CPP main program also #include “school. H” and “student. H”, that is, the definition of student class has been introduced twice, and C + + does not allow the same class to be defined repeatedly.

Some children may think that since school The student class has been introduced in the H file, so remove main CPP main program introduces student H file is OK? In this way, we can avoid the repeated introduction of student class, but this method is not applicable to all “repeated introduction” scenarios.

In C + + multi file programming, there are three ways to deal with the problem of “repeated introduction caused by multiple #include”.

————————

1) Use macro definition to avoid repeated introduction

In actual multi file development, we often use the following macro definitions to avoid repeated introduction:

#ifndef _NAME_H

#define _NAME_H

//Header file content

#endif

Among them_ NAME_ H is the name of the macro. It should be noted that the macro name set here must be unique and not the same as the names of other macros in the project.

When the file is first #include in the program, because_ NAME_ H has not been defined, so it will be defined_ NAME_ H and execute the code of “header file content”; When multiple #include occurs, because it has been defined earlier_ NAME_ H. Therefore, the code in the “header file content” section will not be executed repeatedly.

In other words, we can use the student in the previous project H. modify the document as follows:

#ifndef _STUDENT_H

#define _STUDENT_H

class Student {

    //……

};

#endif

Although the project is main The cpp file still #include “student. H” twice, but in view of_ STUDENT_ The H macro can only be defined once, so the student class will only be defined once. If you execute the project again, you will find that it can be executed normally.

 

2) Use #pragma once to avoid repeated introduction

In addition to the first most commonly used method, you can also use the #pragma one instruction to attach it to the beginning of the specified file, and the file will be #include only once.

We know that #ifndef is to avoid repeated introduction by defining unique macros, which means that the header file must be identified every time, so the efficiency is not high. However, considering that both C and C + + support macro definition, using #ifndef to avoid the possible problem of “repeated introduction of header files” in the project will not affect the portability of the project.

Compared with ifndef, #pragma once does not involve macro definition. When the compiler encounters it, it will immediately know that the current file is introduced only once, so it is very efficient.

However, it is worth mentioning that not every version of the compiler can recognize the #pragma once instruction. Some older versions of the compiler do not support the instruction (a warning will be issued during execution, but the compilation will continue), that is, the compatibility of the #pragma once instruction is not very good.

At present, almost all common compilers support #pragma once instruction, and even visual studio 2017 will bring this instruction when creating a new header file. It can be said that in C / C + +, #pragma once is a non-standard instruction that is gradually supported by many compilers.

In addition, #pragma once can only act on a specific file, not on a specified piece of code like #ifndef.

Here, take the previous “student. H” file as an example, and modify its content to:

#pragma once

class Student {

    //……

};

Run the project again and it can also be executed normally.

 

3) Use_ Pragma operator

C99 standard adds a new one similar to #pragma instruction_ Pragma operator, which can be regarded as an enhanced version of #pragma, can not only realize all the functions of #pragma, but more importantly_ Pragma can also be used with macros.

Relevant_ More functions and usage of pragma operator will not be explained in detail in this section, but only how to use it_ The pragma operator avoids the repeated introduction of header files.

When dealing with the repeated introduction of header files, you can add the following statement to the beginning of the corresponding file:

_Pragma(“once”)

For example, add this statement to the previous project, student H at the beginning of the file, execute the project again, and it can be executed normally.

In fact, in order to prevent users from importing system library files repeatedly, almost all library files adopt one of the above three structures, which is why the compiler will not report errors when importing system library files repeatedly.

 

summary

This section introduces three methods to avoid the repeated introduction of header files, including #pragma once and_ Pragma (“once”) can be regarded as a class, which is characterized by high compilation efficiency but poor portability (the compiler does not support it, will issue a warning, but will not interrupt the execution of the program); And #ifndef is characterized by high portability and poor compilation efficiency. Readers can choose the most practical solution according to the actual situation.

Unless there are strict requirements on the compilation efficiency of the project, readers are strongly recommended to choose the first solution, that is, using #ifndef / #define / #endif combination to solve the repeated introduction of header files.

In addition, in some scenarios, #pragma once and #ifndef are often used together to avoid the repeated introduction of header files in consideration of compilation efficiency and portability. for instance:

#pragma once

#ifndef _STUDENT_H

#define _STUDENT_H

class Student {

    //……

};

#endif

When the compiler can recognize #pragma once, the whole file is compiled only once; Conversely, even if the compiler does not recognize the #pragma once instruction, there is still #ifndef at work.

 

Finally, whether you change careers or start learning, advanced can also be, if you want to learn programming~

[noteworthy] myC / C + + programming learning exchange Club[Click to enter]

Q & A, learning and communication, technical discussion, as well as a collection of super many programming resources, and zero based videos are also great~

Recommended Today

Crash tracking journey of IOS development (I)

Preface: Recently, I encountered a crash blood disaster caused by crash in daily development. In a release in early May, the crash rate of the app developed by the author was directly increased from one thousand to nearly two thousand. At that time, the project leader just needed to report the relevant situation of project […]