参考资料来源于网上,还未经本人实验证明。
1 作用
防止头文件被重复包含和编译。 头文件重复包含会增大程序大小,重复编译增加编译时间。
解释:#ifndef起到的效果是防止一个源文件多次包含同一个头文件。那么一个源文件为什么会两次包含同一个头文件呢?
你写的test.cpp里包含了a.h和b.h,a.h里包含了b.h,所以b.h就会被包含和编译两次。
/*file: test.cpp*/ #include
#include
······ /*file: a.h*/ #include
······
2 缺失ifndef的风险
1、重复定义:
如果b.h中定义了一个变量b,在编译test.cpp时就会报重复定义的错误。
/*file: test.cpp*/ #include
#include
······ /*file: a.h*/ #include
/*file: b.h*/ int b; ······
预处理阶段test.cpp展开头文件后变成:
/*file: test.cpp*/ /*#include
-> #include
*/
int b; ······ /*#include
*/
int b; ······
变量b重复定义。
2、无限循环编译:
你写的test.cpp里包含了a.h和b.h,a.h里包含了b.h,b.h里包含了a.h,所以a.h,b.h就会循环包含,预处理阶段就会不停地循环展开头文件。
/*file: test.cpp*/ #include
#include
······ /*file: a.h*/ #include
······ /*file: b.h*/ #include
······
编译器会报Error #include nested too deeply的错误。
3 解决办法
以无限循环编译中的情况为例,把a.h改写成:
#ifndef _A_H_ #define _A_H_ ... #include
... #endif ······
这样子为什么不会报错了呢?
在预处理阶段,会先展开test.cpp中的头文件a.h,执行到#ifndef _A_H_,发现此时并没有_A_H_并没有被define,所以继续执行#define _A_H_,此时_A_H_就被define了;当展开b.h,执行到文件里的#include,进入
a.h执行#ifndef _A_H_,发现_A_H_已经被define了,所以直接跳到a.h里endif之后的语句执行。这样子就可以保证a.h不会被重复包含。如果要确保b.h不会被重复包含就该写成:
#ifndef _B_H_ #define _B_H_ ... #include
... #endif ······
4 建议
所有头文件前后都加上ifndef/define/endif。
5 reference
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/205600.html原文链接:https://javaforall.net
