在c中假设我们有2个文件
1.h
#include<2.h>
blah blah
我们有 2.H
#include<1.h>
code
这是如何解决的?
答案 0 :(得分:16)
通常,您使用与文件名对应的ifndef / define保护您的包含文件。这不会阻止文件再次被包含,但它确实会阻止使用内容(在ifndef中)并再次触发递归包含。
#ifndef HEADER_1_h
#define HEADER_1_h
#include "2.h"
/// rest of 1.h
#endif
#ifndef HEADER_2_h
#define HEADER_2_h
#include "1.h"
// rest of 2.h
#endif
答案 1 :(得分:7)
好的,为了完整起见,我将首先引用tvanfosson的回答:
你应该使用包含警戒:
// header1.hpp
#ifndef MYPROJECT_HEADER1_HPP_INCLUDED
#define MYPROJECT_HEADER1_HPP_INCLUDED
/// Put your stuff here
#endif // MYPROJECT_HEADER1_HPP_INCLUDED
然而,包含防护并不意味着解决循环依赖问题,它们旨在防止多个包含,这是完全不同的。
base.h
/ \
header1.h header2.h
\ /
class.cpp
在这种情况下(很常见),你只需要将base.h包含一次,这就是包含警卫的内容。
所以这样可以有效防止双重包含...... 但是你无法编译!!
可以通过尝试推理编译器来解释问题:
最后,你会留下一大堆错误信息,但至少编译器不会崩溃。
解决方案是以某种方式消除对此循环依赖的需要。
这将解决循环依赖(手动)在编译器中没有任何魔法可以为你做。
答案 2 :(得分:0)
循环内容必须消除,而不是“包含警卫”解决“(如接受的答案所示)。考虑一下:
1.H:
#ifndef HEADER_1_h
#define HEADER_1_h
#include "2.h"
#define A 1
#define B 2
#endif // HEADER_1_h
2.H:
#ifndef HEADER_2_h
#define HEADER_2_h
#include "1.h"
#if (A == B)
#error Impossible
#endif
#endif // HEADER_2_h
main.c中:
#include "1.h"
这将在编译时抛出“不可能”错误,因为“2.h”由于包含警卫而未能包含“1.h”,并且A
和B
都变为0。实际上,这会导致很难跟踪出现和消失的错误,具体取决于包含头文件的顺序。
这里的正确解决方案是将A
和B
移至“common.h”,然后将其包括在“1.h”和“2.h”中。
答案 3 :(得分:-1)
既然您在c ++标签和c下发布了您的问题,那么我假设您使用的是c ++。在c ++中,您还可以使用 #pragma once 编译器指令:
1.H:
#pragma once
#include "2.h"
/// rest of 1.h
2.H:
#pragma once
#include "1.h"
/// rest of 2.h
结果是一样的。但有一些注意事项:
pragma一般会编译得更快,因为它是一个更高级别的机制,并且不会像包含警卫一样在预处理中发生
有些编译器已经知道错误“处理”#pragma一次。虽然大多数(如果不是全部)现代编译器都能正确处理它。有关详细列表,请参阅Wikipedia
编辑:我认为c编译器也支持该指令,但从未尝试过,而且,在我看过的大多数c程序中,包括防护是标准(可能是由于编译器限制处理pragma一次指令? )