C 中的标头相互包含
在 C 中,标头有时需要相互包含。但是,这可能会导致问题,尤其是在放置 #include 语句的位置时。
内部或外部宏
一般来说,#include 语句应该放置在宏内部,例如#ifndef include Guards。这可以防止编译过程中的无限递归,如下例所示:
<code class="cpp">// A.h #ifndef A_H_ #define A_H_ #include "B.h" class A { private: B b; public: A() : b(*this) {} }; #endif // A_H_</code>
<code class="cpp">// B.h #ifndef B_H_ #define B_H_ #include "A.h" class B { private: A& a; public: B(A& a) : a(a) {} }; #endif // B_H_</code>
将 #include 语句放在宏之外会导致编译器由于 A.h 和 B.h 之间的相互包含而无限递归
未声明的类型
但是,将 #include 语句放在宏内可能会导致未声明类型的问题。例如,考虑以下代码:
<code class="cpp">// A.h #ifndef A_H_ #define A_H_ class A; // Forward declaration #include "B.h" class A { private: B b; public: A() : b(*this) {} }; #endif // A_H_</code>
<code class="cpp">// B.h #ifndef B_H_ #define B_H_ #include "A.h" class B { private: A a; // Directly include A public: B(A& a) : a(a) {} }; #endif // B_H_</code>
在这种情况下,编译器会抱怨 A 是 B.h 中未声明的类型。这是因为当包含 B.h 时,A.h 中的前向声明是不可见的。
解决方案:前向声明
要解决这些问题,最好使用前向声明并在必要时包含包含完整定义的标题。在此示例中,应将 A 的前向声明添加到 B.h 的 B 定义之前:
<code class="cpp">// B.h #ifndef B_H_ #define B_H_ class A; // Forward declaration #include "A.h" class B { private: A a; // Directly include A public: B(A& a) : a(a) {} }; #endif // B_H_</code>
以上是如何处理 C 中标头之间的循环依赖关系?的详细内容。更多信息请关注PHP中文网其他相关文章!