【问题标题】:C++ breaking cyclic includesC++ 打破循环包括
【发布时间】:2016-04-28 19:51:44
【问题描述】:

我可能已经知道答案了,但我还是想看看是否有人能想出一个更好的主意。

在较大的库中,我有许多类相互交叉引用。我通常通过向前声明这些类来解决这个问题。但是,为了便于使用,我通常为可以出现在 shared_ptr 中的类定义一个 ref 类型,如下所示:

class A : public B {
public:
  typedef std::shared_ptr<A> Ref;
};

它允许更好的引用:A::Ref a 而不是 std::shared_ptr&lt;A&gt; a。我现在看到的问题是,使用这样的 Ref 需要实际包含该头文件,从而导致循环包含。我无法在包含前向声明的文件中定义 Ref 类型,因为 XCode 使用这样的共享指针为 var 显示完全虚假的值。

还有哪些其他选项可以同时做到这一点:在真实类型上定义了 Ref,但不需要包含包含该类型的标头?

【问题讨论】:

    标签: c++


    【解决方案1】:

    实际上,我不确定你能否解决这个确切的问题。

    但如果只是为了让你的代码更漂亮,你可以稍微改变一下逻辑。

    有一个命名空间 Refs,您可以在其中定义您的 typedef。例如:

    namespace Refs { typedef std::shared_ptr<::A> A; }
    

    因此,您使用Refs::A 代替A::Ref。我同意这有点不合逻辑,但至少打字不会太长。现在,您可以在各种标头中定义此类类型定义,并最终转发声明它们(当然,前提是您之前也转发声明了该类)。

    其他选项

    但实际上,如果我是你,我会为 std::shared_ptr 使用别名(这需要 C++11):

    template<class T> using Ref = std::shared_ptr<T>;
    

    那么你不需要在任何类或命名空间中声明任何东西。用Ref&lt;A&gt;就行了,更灵活更清晰。

    【讨论】:

    • 这可能是要走的路。在上面的 / 封闭命名空间中向 A 添加一个前向声明,并将其放在标题中。
    • Ref 模板别名确实是这里最好的解决方案,完美地满足了这两个条件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-03
    • 2013-01-30
    • 1970-01-01
    • 1970-01-01
    • 2021-03-11
    相关资源
    最近更新 更多