【问题标题】:Unnecessary includes in c++c++ 中不必要的包含
【发布时间】:2018-11-08 08:35:10
【问题描述】:

我的问题是关于 C++ 中的包含。想象一下这 3 个 .h 文件

// A.h
#include "B.h"
class A {
    B b;
}
// B.h
#include "C.h"
class B {
    C c;
}
// C.h
class C {

}

这里的问题是,A.h 需要访问 B.h,而不是 C.h。

在这种情况下,A.h 可以通过 B.h 访问 C.h,因此这是不必要的包含。最近我经常遇到这种情况,所以我想知道如何避免这种情况。

【问题讨论】:

  • 是的,A.h 需要 C.h,因为它使用 B,它使用 C。你在问什么?
  • 使用 include 保护 所以顺序不重要。
  • @DeadlyCow "'A' 从不实例化 'C' 类型的变量" 它确实通过实例化 @987654324 来实例化 C @.
  • 不必要的包含示例是#include C.h in A.h
  • 经验法则是:包括您使用的内容。 A 依赖于 B,所以 A 应该包含 B。B 依赖于 C,所以 B 应该包含 C。还要使用标头保护,或 #pragma once

标签: c++ include header-files


【解决方案1】:

这里的问题是,A.h 需要访问 B.h,而不是 C.h。

您的代码中没有不必要的包含。 A.h 不需要直接包含C.h,但A.h 不能在没有(间接)包含C.h 的情况下使用B.h

【讨论】:

    【解决方案2】:

    首先;在许多情况下,您不需要类型的完整定义(仅使用指针或对其的引用或将其用作返回值时)。在这些情况下,您可以使用前向声明而不是包含完整的标头。 其次;如果您的标头具有适当的包含保护,那么多次包含它们的成本非常低。

    我知道没有好的工具可以找到不需要的包含(谷歌“包含你使用的东西”工具试过,但根据我的经验并不能很好地工作)。恐怕您只需要使用您对代码的了解来识别不需要的包含并手动删除它们。

    【讨论】:

    • 多次包含文件的问题没有任何意义。
    • @Barmar 不,没有。我扩大了一点 - 所以,射击我;-)
    【解决方案3】:

    我不认为这是可以做到的。在 c++ 中,包含#include 指令的预处理器返回一个文本文件,然后实际的编译器会处理该文件。这是目前将代码导入项目的唯一方法。如果B.h 需要C.h,则它必须以文本形式存在于A.h 之前。

    c++ 编译器无法在一个翻译单元中“忘记”以前需要的定义。

    【讨论】:

      【解决方案4】:

      按照上面的建议使用包含防护。

      #ifndef _A_H_
      #define _A_H_
      #include B.h
      class A {
          B b;
      }
      #endif
      

      您还可以使用指向类的指针,然后显式构造和删除类。一个没有引用类成员和方法的内联代码的包含文件只需要知道它包含的东西是类,就可以拥有一个指向该类的成员。我认为这可能是一种封装形式,但我找不到一个很好的例子。

      class B;
      class A {
          B * b;
      }
      

      【讨论】:

      • 'include guards' 和 '#pragma once' 不一样吗?
      • @DeadlyCow • 它们的用途相同。 #pragma once 是一个扩展(由大多数 C++ 供应商实现),而不是标准的一部分。
      猜你喜欢
      • 2011-03-10
      • 2013-03-17
      • 1970-01-01
      • 2015-07-15
      • 1970-01-01
      • 1970-01-01
      • 2010-11-03
      • 2021-11-10
      • 1970-01-01
      相关资源
      最近更新 更多