C++头文件保护符

头文件保护符定义

头文件保护符(Header guards)的主要作用是防止头文件在同一个编译单元中被多次包含。这可以避免因多次包含相同的头文件导致的编译错误,例如重复定义类、函数或变量。头文件保护符是通过使用预处理器指令 #ifndef#define#endif 实现的。

#define: 把一个名字设定为预处理变量,另外两个指令则分别检查某个指定的预处理变量是否定义;

#ifdef: 当且仅当变量已定义时为真;

#ifndef: 当且仅当变量未定义时为真;

注意:ifdefifndef 一旦检查结果为真,则执行后续程序直至遇到 endif 为止。

简单实例

假设我们有一个名为 my_class.h 的头文件,其中定义了一个名为 MyClass 的类:

1
2
3
4
5
6
7
8
9
10
11
12
// my_class.h

#ifndef MY_CLASS_H
#define MY_CLASS_H

class MyClass {
public:
void print_hello();
};

#endif // MY_CLASS_H

在这个头文件中,我们使用了头文件保护符。#ifndef MY_CLASS_H 检查一个名为 MY_CLASS_H 的宏是否已被定义。如果尚未定义,编译器会继续处理 #define MY_CLASS_H,将 MY_CLASS_H 定义为宏,并包含 MyClass 的定义。#endif 结束了这个条件编译块。

现在,假设我们有一个名为 main.cpp 的源文件,它包含了 my_class.h

1
2
3
4
5
6
7
8
9
10
11
// main.cpp

#include "my_class.h"
#include "my_class.h" // 这里再次包含了同一个头文件,但是没有问题,因为有头文件保护符

int main() {
MyClass obj;
obj.print_hello();

return 0;
}

main.cpp 中,我们包含了 my_class.h 头文件两次。如果没有头文件保护符,这将导致 MyClass 类被重复定义,从而引发编译错误。由于我们使用了头文件保护符,当第二次尝试包含 my_class.h 时,MY_CLASS_H 宏已经被定义,因此 #ifndef MY_CLASS_H 的条件为 false,MyClass 的定义不会再次被包含。

这个简单的例子展示了头文件保护符如何防止头文件在同一个编译单元中被多次包含,从而避免了编译错误。