谁能告诉我如何确定哪些类导致了我所看到的循环依赖问题?
最佳答案
在这种情况下会出现循环依赖的典型问题:
// foo.h
#ifndef FOO_H
#define FOO_H
#include "bar.h"
struct Foo { void use(Bar); };
#endif // FOO_H
// bar.h
#ifndef BAR_H
#define BAR_H
#include "foo.h"
struct Bar { void use(Foo); };
#endif // BAR_H
// bar.cpp
#include "bar.h"
当预处理器处理 bar.cpp
时会发生以下情况:
// bar.cpp
// #include "bar.h"
// BAR_H is not defined
// #define BAR_H
// #include "foo.h"
// FOO_H is not defined
// #define FOO_H
// #include "bar.h"
// BAR_H is defined, skip
// #endinclude "bar.h"
struct Foo { void use(Bar); }; // ERROR: Bar is not defined
// #endinclude "foo.h"
struct Bar { void use(Foo); }; // OK: Foo is defined
// #endinclude "bar.h"
这可能会使用预处理器技巧检测到,以便在编译时显示一个很好的消息。然而,它有点复杂,并且增加了已经必要的包含保护程序......所以大多数时候,你只是尝试编译,如果它没有,并且你无法理解错误,你总是可以得到使用编译器开关(在 gcc 上为 -E)的预处理文件。
现在,进入预处理器技巧。我们可以看到的问题是,即使定义了 BAR_H
,该文件还没有被包含在内。
解决方案是准备另一个守卫,以表明整个文件已被处理的事实,并在我们处于仅定义两个守卫之一的情况下发出错误。
看起来是这样的:
// bar.h
#ifdef BAR_H
#ifndef BAR_H_2
# error "Cyclic inclusion involving bar.h"
#endif // BAR_H_2
#else
#include "foo.h"
struct Bar { void use(Foo); };
#define BAR_H_2
#endif // BAR_H
不过如您所见,对于相对较低的频率错误,它使头部防护装置已经需要的麻烦增加了一倍。所以它通常被认为不值得。
关于c++ - 如何识别 C++ 中循环依赖的来源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5700393/