这在多大程度上是一种不好的做法? [循环依赖]

时间:2013-04-11 16:19:45

标签: c++ c++11 circular-dependency

(首先,对不起我的英语)

为了避免循环依赖的句法限制,我想知道以下提出的解决方案是否真的是一个解决方案,或者它是否具有比冒险更多的不满(让我认为这种相互依赖是不可避免的):

原始情况:

class B;

class A
{
   B needed;
};

class B {};

输出:

B has an incomplete type.

“解决方案”:

template<typename T = class B>
class tricky_A
{
    static_assert(is_same<T, B>::value, "Too tricky!!");

    T needed;
};

class B {};

using A = tricky_A<>;

int main()
{
   A a;  // At the instantiation point, B isn't an incomplete type.
}

输出:

No problems.

常见的解决方案是使用指针,但是当你真的不需要时我会看到两个问题:

1)如果您决定保留指向其他本地对象的指针,您应该确定(或者您的类的用户应该确定)对象的生命周期短于“保留”对象的生命周期。 / p>

2)如果你决定处理动态内存,你应该花时间预留和破坏内存,而且它会强迫你处理异常处理,以使你的代码异常安全。

*)更长的代码;可读性较小;更难维持;等

我应该使用这个“解决方案”还是更好地搜索其他人?

编辑:你没事。这不是一个真正的循环依赖,所以,没有什么可以问的。这个问题可以关闭。

EDIT2 :更好的问题here

2 个答案:

答案 0 :(得分:1)

我认为使用指针(我同意@Andy Prowl RE:智能指针)是首选解决方案。关于你关于更长的代码,更小的可读性,更难维护的观点 - 你的“棘手”解决方案虽然聪明,但却违反了所有这些租户 - 它更长,更难阅读,更难维护。中级C ++开发人员的入门应该知道如何处理指针和智能指针,但是很难期望他们理解你提出的模板解决方案。

我也没有在你的例子中看到循环依赖;我会假设B也取决于A

处理此类设计时需要记住的重要事项包括:

  • 分隔标题和正文很有帮助
  • 希望按以下顺序执行#includes:正文#includes,正向引用#includes,最后(如有必要),标题#includes

答案 1 :(得分:1)

你设计的前提是错误的。由于代码中没有循环依赖,因此无需修复(除了在B之前找到A的定义),并且不需要进行额外的工作。

如果您修复测试用例以包含真正的循环依赖关系,您会发现解决方案无法解决问题。所以基本上你有更多的代码更复杂,但仍然是同样的问题。

另请注意,处理循环依赖关系的正确方法是打破它。一旦循环依赖性消失,管理它的需求也就消失了。很少有好的设计包含真正的循环依赖。