如果每个标头使用#ifndef
这是否意味着不会发生有关循环依赖的编译器错误?
答案 0 :(得分:4)
不,它没有。
这意味着编译器不会尝试为无穷大包含头,但循环依赖仍然会产生逻辑问题,因为编译是从上到下执行的。我们来看看为什么:
#ifndef A_H
#define A_H
#include "b.h"
struct A
{
B* ptr;
};
#endif
#ifndef B_H
#define B_H
#include "a.h"
struct B
{
A* ptr;
};
#endif
#include "a.h"
int main()
{
A a;
}
包含保护使我们能够实际运行预处理器并让它在不到无限的时间内完成其工作;实际上,这么快,我已经在手下完成了。结果是:
struct B
{
A* ptr;
};
struct A
{
B* ptr;
};
int main()
{
A a;
}
B
的定义出现在A
的定义之前,因此无法理解A* ptr;
。当然,你可以解决这个问题,但只能通过颠倒包含的顺序,然后你就会遇到相反的问题。前向声明和/或重新架构是解决它的唯一方法。
标题保护解决不同的问题。他们不允许您随意做任何事情。
答案 1 :(得分:0)
它不会创建任何循环依赖,它会多次包含该文件,因为名称'include'表示。这通常发生在代码库很大且我们不知道这个文件是否已被另一个头文件包含的时候。
我们也可以使用单个语句,#pragma once