C++ 使用一个大include文件的优点/缺点

C++ 使用一个大include文件的优点/缺点,c++,include,header-files,C++,Include,Header Files,我有一个个人项目,我怀疑它会超过20对头/cpp文件。我想知道是否最好让每个头文件和cpp文件都包含它需要的其他文件(或使用转发声明),或者让每个文件都包含“Includes.hpp”,而“Includes.hpp”又包含所有标准库,为每个类提供转发声明,然后包含我的所有其他头文件 如我所见,使用一个大的头文件: 把一切都打扫干净 使从其他目录中包含这些文件变得更容易(因为您只需要导航到使用一个文件,然后该文件将链接所有其他文件) 将包含每个编译的所有文件,考虑到这是一个小项目,这不是一个缺点

我有一个个人项目,我怀疑它会超过20对头/cpp文件。我想知道是否最好让每个头文件和cpp文件都包含它需要的其他文件(或使用转发声明),或者让每个文件都包含“Includes.hpp”,而“Includes.hpp”又包含所有标准库,为每个类提供转发声明,然后包含我的所有其他头文件

如我所见,使用一个大的头文件:

  • 把一切都打扫干净
  • 使从其他目录中包含这些文件变得更容易(因为您只需要导航到使用一个文件,然后该文件将链接所有其他文件)
  • 将包含每个编译的所有文件,考虑到这是一个小项目,这不是一个缺点,因为我将使用所有的文件
这是个好主意吗?

不太好

注意,便利标题的使用确实存在,它们可以用于打包组合在一起的功能,如果您认为90%的时间标题的客户端也需要包含对象的完整定义,那么也可以在标题文件中使用
包含
而不是转发声明

然而,全局标题是不好的样式,虽然您的项目现在很小,但以后可能会增长。在不得不解开这类事情并重新点燃标题后,我只能说:没有乐趣

这到底有什么好处呢?如果项目很小,那么开始时几乎没有标题,因此它是边缘的。

不太可能

注意,便利标题的使用确实存在,它们可以用于打包组合在一起的功能,如果您认为90%的时间标题的客户端也需要包含对象的完整定义,那么也可以在标题文件中使用
包含
而不是转发声明

然而,全局标题是不好的样式,虽然您的项目现在很小,但以后可能会增长。在不得不解开这类事情并重新点燃标题后,我只能说:没有乐趣


这到底有什么好处呢?如果项目很小,那么开始时几乎没有标题,因此它是边缘的。

老实说,我不会这么做。您提到您的项目将只有大约20个cpp文件,但您没有提到这些文件有多大以及它们包含的代码有多复杂。如果将所有内容都放在一个大标题中,每次都必须重新编译这20个文件,如果这些文件包含大量代码,则编译时间将显著增加

当然,如果您想要包含在大标题中的所有内容都是来自标准库的标题或您不会修改的标题,那么您可以将它们全部放在预编译的标题中,并让所有cpp文件都包含它

但是,如果有要修改的标题(例如更改类定义、添加typedef等),则应注意每次修改都需要重新编译所有cpp文件。根据这些文件的大小,每次小的编辑(更改函数名、添加空白、添加注释)都可能会将工作延迟一分钟,而这可能需要五秒钟(如果您使用的是更复杂的库,如Boost.Spirit,则这些时间增长得非常快)


总而言之,如果您正在处理一个需要维护的项目,我不会将所有内容都放在一个文件中,即使该项目现在很小。

老实说,我不会这样做。您提到您的项目将只有大约20个cpp文件,但您没有提到这些文件有多大以及它们包含的代码有多复杂。如果将所有内容都放在一个大标题中,每次都必须重新编译这20个文件,如果这些文件包含大量代码,则编译时间将显著增加

当然,如果您想要包含在大标题中的所有内容都是来自标准库的标题或您不会修改的标题,那么您可以将它们全部放在预编译的标题中,并让所有cpp文件都包含它

但是,如果有要修改的标题(例如更改类定义、添加typedef等),则应注意每次修改都需要重新编译所有cpp文件。根据这些文件的大小,每次小的编辑(更改函数名、添加空白、添加注释)都可能会将工作延迟一分钟,而这可能需要五秒钟(如果您使用的是更复杂的库,如Boost.Spirit,则这些时间增长得非常快)

总而言之,如果您正在处理一个需要维护的项目,我不会将所有内容都放在一个文件中,即使该项目现在很小。

我想说,总的来说,这是一个坏主意,原因有几个:

  • 它给了你糟糕的封装:客户端应该只拉入他们需要的头。通过这种方法,包含的内容将包含所有内容,正如Alok提到的,这将增加构建时间和对重建的敏感性
  • 接口类和实现类之间没有区别,即您库的客户端使用的类和该库内部使用的、客户端不需要(或者不应该)看到的类
  • 如果您的任何头定义了宏,那么这些宏现在可能会“泄漏”到包含该头的任何其他代码中,这可能是不需要的。任何必须输入
    #undef MIN
    的人都会知道这种痛苦
  • 如果您有几个类需要相互了解,那么就有可能出现递归包含,因此它可能对包含顺序很敏感,或者您将得到包含循环
我认为虽然有一个例子是可以接受的,那就是如果您的库只提供了几个打算由客户端调用的类/函数,而其余的都只是实现使用的内部类。因此,客户可以只包括