关于标题,转发和如何组织很多包含

About headers, forwards and how to organize a lot of includes

本文关键字:何组织 包含 转发 于标题 标题      更新时间:2023-10-16

我有3个类(它可能是300),每一个都有自己的头和实现。我想写一种"优雅"的方式来组织我加载三个类中每个类所需的任何类的方式。也许这个例子有帮助……

我有:class1 class2 class3

每个标头都有:

#ifndef CLASS#_H 
#define CLASS#_H   
  #define FORWARD_STYLE
  #include "general.h"
 #endif

每个实现都有:

  #define DIRECT_STYLE
  #include "general.h"

好吧我将编写一个'general.h'文件,其中包含:

#ifndef DIRECT_STYLE 
#ifndef CLASS1_H
#include "class1.h"
#endif
#ifndef CLASS2_H
#include "class2.h"
#endif
#ifndef CLASS3_H
#include "class3.h"
#endif
#endif
#ifndef FORWARD_STYLE 
class Class1;
class Class2;
class Class3;
#endif
// a lot of other elements needed 
#include <string.h>
#include <stdio.h"
....
#include <vector.h" 
( all the class I need now and in the future )

这是一个好的结构吗?还是我在做蠢事?我的目标是有一个唯一的"general.h"文件来编写我需要的所有元素……这能正常工作吗?由于

要遵循的基本规则是:

  1. 让每个源文件包含以独立方式编译所需的所有头文件。避免让头文件通过其他文件间接包含在源文件中。
  2. 如果你有在大多数源文件中都需要的结构,那么把它们放在一个通用的头文件中,并在中包含头文件,只有在那些需要它的源文件中包含
  3. 尽可能使用Forward声明。当您可以使用它们时,有几个限制,请阅读这个以了解更多关于这些场景的信息。
总的来说,避免通过公共头文件在源文件中包含不必要的代码是一个好主意,因为它只会导致代码膨胀,所以尽量将其保持在最低限度。包含头文件实际上只是复制粘贴整个头文件到源文件,并且包含不必要的文件有几个缺点,即:
  1. 增加编译时间
  2. 全局命名空间污染。
  3. 预处理器名称可能冲突。
  4. 增加二进制大小(在某些情况下,但并非总是如此)

现在看来这可能是个好主意,但无法扩展,应该避免使用。您的general.h文件将包含大量文件,因此包含它的所有文件将(a)由于内存限制而需要很长时间才能编译或根本无法编译,并且(b)每次任何更改都必须重新编译。

在每个文件中直接包含所需的头文件,并定义几个前向声明文件,这样就可以了。

标题中的#define可能没有问题,但它可以通过许多源传播,并可能导致问题。更严重的是,任何时候general.h或它的任何包含更改您的整个项目重建。对于小项目,这不是问题,但对于大项目,它将导致不可接受的构建时间。

相反,我使用一些指导原则:

  • 在头文件中,向前声明你可以,无论是显式或#include "blah_fwd.h"在标准库中看到。
  • 所有的头文件应该能够自己编译,而不是依赖于源文件,包括以前的东西。这可以很容易地被所有的源文件检测到,总是首先包含自己的头文件。
  • 在源文件中,包括你需要的东西(通常你不能摆脱源文件中的前向声明)。
  • 还注意永远不要在头文件中使用using,因为它会污染全局命名空间。

如果这看起来像很多工作,不幸的是,那是因为它是。这是一个继承自C语言的系统,需要程序员进行一定程度的维护。如果你想在一个较高的层次上决定你的项目使用什么,并让编译器/运行时找出它,也许c++不是适合你的项目的语言。