关于C++的头文件define

在C++的头文件中,一般开都我们总会看到#ifndef xxx, #define xxx这两行代码,下面简单记录一下这两行代码的作用

1.头文件基本格式
C++的头文件的作用就是声明变量和函数,每个头文件基本都是如下格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef  _TEST_H_
#define _TEST_H_

#include <math.h> // 引用标准库的头文件
#include “header.h” // 引用非标准库的头文件

double m_counter // 成员变量声明

void Function1(…); // 全局函数声明

class Box // 类结构声明
{

};

#endif

2.具体作用
这个 “ ifndef “ 是 “ if not define ” 的缩写,表示如果没有定义这个变量 _TEST_H_,就定义这个变量 _TEST_H_,并执行下面的变量生声明和函数声明。

下面说说这两行的作用,简单的来说,就是“防止该头文件被重复引用”。

简单地举个例子,假设你的工程里面有4个文件,分别是:
a.cpp;
b.hpp;
c.hpp;
d.hpp;

我们在a.cpp的头部include了b.hpp以及c.hpp:

1
2
#include  "b.hpp"
#include "c.hpp "

然后b.hpp和c.hpp这两个文件有包含了d.hpp文件:

1
#include  "d.hpp "

在这情况下,编译器在编译a.cpp文件时,首先会根据“ #include “b.hpp” ”编译b.hpp,再根据b.hpp文件中的“ #include “d.hpp “ ”编译d.hpp文件。

接着根据第二行“ #include “c.hpp” ”编译c.hpp,然后再根据c.hpp文件中的“ #include “d.hpp “ ”编译d.hpp文件,然而实际上这个d.hpp文件我们已经编译过了,这就会造成重复的编译,甚至是错误。

“ #ifndef/#define/#endif ”,就是为了防止这种重复声明导致的编译时间变长或者编译错误的情况,因为加了这几行,编译器只会编译一次。在比较复杂的系统中,可以大大将少编译时间。

3.“ #ifndef/#define/#endif ” 一定要加吗?
我个人观点:加了总比不加好,从代码的规范和代码的健壮性来讲,加了只有好处没有坏处,毕竟就三行代码,敲一下有不会累死人。不加的话可能暂时看不出问题,但指不定那天冒出问题,让你debug半天。何必自己跟自己过不去呢?

再多说几句,这里的变量名一般是头文件名大写,中间用下划线“_”分开,比如“ _TEST_H_”。

More Answer

这个问题的答案在stackoverflow上已经有人回答了,下面是网上的答案。

Once the header is included, it checks if a unique value (in this case  HEADERFILE_H) is defined. 

Then if it's not defined, it defines it and continues to the rest of the page.

When the code is included again, the first ifndef fails, resulting in a blank file.

That prevents double declaration of any identifiers such as types, enums and static variables.