在头文件和源文件中包含#includes

Rob*_*tah 49 c++ header file include

我喜欢将所有#includes放在我的头文件中,然后在源文件中只包含我的头文件.什么是行业标准?我的方法有任何缺点吗?

tza*_*man 68

通常,您只想将最小必要包含放入类头文件中,因为使用该标头的任何其他人也将被强制使用#include它们.在较大的项目中,这会导致构建速度降低,依赖性问题以及各种其他肮脏问题.

可以将头文件视为类的公共接口.你不想鞍大家谁用额外的依赖使用它,除非他们是必要的,以便能够使用类.

将类实现中仅需要的任何内容移动到源文件中.对于标题中使用的其他类,#include如果您确实需要知道标题中的大小或内容,则只有标题 - 其他任何内容和前向声明就足够了.大多数情况下,您只需要#include继承自的类,以及其对象是您的类的值成员的类.

这个页面有一个很好的总结.(以下复制供参考)


C++头文件包含模式#

大型软件项目即使在C语言编程时也需要仔细的头文件管理.当开发人员转向C++时,头文件管理变得更加复杂和耗时.这里我们提供一些头文件包含模式,这将简化这项工作.

头文件包含规则

在这里,我们讨论简化头文件管理所需的C++头文件包含的基本规则.

只有在前向声明不能完成工作时才应包含头文件.头文件的设计应使头文件包含的顺序不重要.这是通过确保它x.h是第一个头文件来实现的x.cpp .头文件包含机制应该容忍重复头文件包含.以下部分将借助示例解释这些规则.

头文件包含示例

以下示例说明了不同类型的依赖项.假设A类的代码存储在a.cpp和中a.h.

a.h

#ifndef _a_h_included_
#define _a_h_included_
#include "abase.h"
#include "b.h"

// Forward Declarations
class C;
class D;

class A : public ABase
{
  B m_b;
  C *m_c;
  D *m_d;

public:
  void SetC(C *c);
  C *GetC() const;

  void ModifyD(D *d);
};
#endif
Run Code Online (Sandbox Code Playgroud)

a.cpp

#include "a.h"
#include "d.h"

void A::SetC(C* c)
{
  m_c = c;
}

C* A::GetC() const
{
  return m_c;
}

void A::ModifyD(D* d)
{
  d->SetX(0);
  d->SetY(0);
  m_d = d;
}
Run Code Online (Sandbox Code Playgroud)

文件包含分析

让分析头文件夹杂物,从所涉及的本实施例中的类点,即ABase,A,B,CD.

  • ABase类: ABase是基类,因此需要类声明来完成类声明.编译器需要知道大小ABase以确定总大小A.在这种情况下abase.h应明确包括在内a.h.
  • B类: Class A包含Class Bby value,因此需要类声明来完成类声明.编译器需要知道B的大小来确定总大小A.在这种情况下b.h应明确包括在内a.h.
  • C类:Class C仅包含在指针引用中.大小或实际内容Ca.h或不重要a.cpp.因此,只包含了前瞻性声明a.h.请注意,c.h未包含在a.h或中a.cpp.
  • D类:Class D仅用作指针引用a.h.因此,前瞻性声明就足够了.但在实质上a.cpp使用类D,所以它明确包括d.h.

关键点

只有在前向声明不能完成工作时才应包含头文件.通过不包括c.hd.h类的其他客户端A永远不必担心c.h,d.h除非他们按值使用C类和D类. a.h已被列为第一个头文件.a.cpp这将确保a.h不希望之前包含某些头文件a.h.由于a.h已作为第一个文件包含在内,因此成功编译a.cpp将确保a.h不会期望之前包含任何其他头文件a.h.如果对所有类都遵循,(即x.cpp始终包括x.h作为第一个头),则不依赖于头文件包含. a.h包括检查符号的预处理器定义_a_h_included_.这使得它能够容忍重复的内含物a.h.

循环依赖

XY以下示例之间存在循环依赖关系.通过使用前向声明来处理此依赖项.

x.h and y.h

/* ====== x.h ====== */
// Forward declaration of Y for cyclic dependency
class Y;

class X 
{
    Y *m_y;
    ...
};

/* ====== y.h ====== */
// Forward declaration of X for cyclic dependency
class X;

class Y 
{
    X *m_x;
    ...
};
Run Code Online (Sandbox Code Playgroud)