#ifndef class_a_h__
#define class_a_h__
// Forward declare class A
class A;
// Include dependencies here in case they require class A.
#include "class_b.h"
// Actually declare class A
class A {
void SetB(B* b);
// other fields and methods that may use b
};
#endif // class_a_h__
class_b.h
#ifndef class_b_h__
#define class_b_h__
// Forward declare class B
class B;
// Include dependencies here in case they require class B
#include "class_a.h"
// Actually declare class B
class B {
public:
void SetA(A* a);
// other fields and methods that may use a
};
#endif // class_b_h__
3条答案
按热度按时间0pizxfdo1#
许多人认为最好首先避免循环依赖。
假设您有两个文件,其中
a.cc
#包含b.h
,b.cc
#包含a.h
:bazel
将报告循环依赖。如果你拥有所有有问题的代码,避免这些循环依赖的更直接的方法是重新整理你的源代码和bazel包,首先避免依赖。
这里的一个策略是将常见的东西重构为第三个“核心”库
c
,它既不依赖于a
也不依赖于b
:另一种策略是使用某种构建步骤将
a.h
和b.h
复制到某个“公共头文件”文件夹(该文件夹本身不依赖于任何其他文件)。这将删除文件级循环依赖,但从语义上讲,源代码在a
和b
之间仍然存在循环依赖。bq9c1y662#
如果您不拥有这些库,则必须等到实现cc_import-kind-of-rule。参见issue #818。我暂时还不知道有什么变通办法。
pn9klfpd3#
假设你有两个类A和B,如下所述,它们是有效的C++,并且你在设置构建规则时遇到了麻烦。您有几个选项可以修改构建规则或重构代码。
class_a.h
class_b.h
选项一:声明libA和libB,但不声明它们的相互依赖性。
这里的神奇之处在于在依赖类lib的src中包含其他类的头文件。你可以让一个人依赖另一个人,但不能同时依赖两个人。
优点:
缺点:
BUILD.bzl
选项二:创建一个同时包含类A和类B的库。
我对这一点百感交集,但这可能是我默认的建议。由于循环依赖性,你不应该只使用一个库而不使用另一个库,所以我认为把它们组合成一个目标是可以的。
优点:
缺点:
BUILD.bzl
选项三:提取基类。
这可以是一种选择,但对于任何现实世界的场景来说都是复杂的。你是否创建了以A和B为参数的类C,然后使用A和B,使用C,或者根据你需要它们如何工作的其他排列。我很确定这对于像事件总线这样知道事件处理程序的东西是不可能的,而处理程序需要知道总线来发送其他事件。
优点:
缺点:
选项3a:将A类和B类合并为一个类。
如果这是您的一个选项,那么它是一个更简单的重构选项。这些类显然已经相关。也许它们作为一个类更有意义。
优点:
缺点: