包含防护确实可以保护你的头文件来自相互的、递归的包含。之所以会出现混乱,是因为问题不在于守卫,而在于头文件中数据结构的定义方式。
考虑这个例子:
// a.h #ifndef A_H #define A_H #include "b.h" struct A { ... }; #endif // A_H // b.h #ifndef B_H #define B_H #include "a.h" struct B { A* pA; }; #endif // B_H // main.cpp #include "a.h" int main() { ... }
即使使用包含守卫,main. cpp 将无法编译,因为类 A(类 B 所需)的定义不完整。前向声明解决了此问题:
// b.h #ifndef B_H #define B_H // Forward declare A to avoid circular inclusion struct A; struct B { A* pA; }; #endif // B_H
包含防护措施,可以防止单个翻译单元内出现多个定义,但不能跨不同单元。举例来说:
// header.h #ifndef HEADER_H #define HEADER_H int f() { return 0; } #endif // HEADER_H // source1.cpp #include "header.h" // Redundant include causing multiple definitions #include "header.h" int main() { ... } // source2.cpp #include "header.h" ...
即使有包含保护,链接器也会抱怨 f() 的多个定义。解决方案是仅在一个翻译单元中定义函数,或者使用 inline 关键字指示编译器在每个调用点内联函数体。
以上是Include Guards 如何处理相互递归和多个符号定义?的详细内容。更多信息请关注PHP中文网其他相关文章!