C++ 将所有项目头放在一个文件headers.h中是一个好主意吗?
前几天我和我的导师谈过,问了他这个问题。他告诉我,我可以进行较小的项目,但我正在启动一个国际象棋程序,我想知道Stack Overflow对这个问题的看法。我应该将所有标题包含到一个文件中,还是将它们分开?一般来说,这是一个坏主意,因为在这种情况下,您可能存在无法解决的依赖项C++ 将所有项目头放在一个文件headers.h中是一个好主意吗?,c++,header,C++,Header,前几天我和我的导师谈过,问了他这个问题。他告诉我,我可以进行较小的项目,但我正在启动一个国际象棋程序,我想知道Stack Overflow对这个问题的看法。我应该将所有标题包含到一个文件中,还是将它们分开?一般来说,这是一个坏主意,因为在这种情况下,您可能存在无法解决的依赖项 但是,创建一个头文件通常是一个好主意,其中包含您正在使用的来自不同库的所有基本头文件或您自己的头文件(具有结构和数据类型定义)。没有万能的解决方案。以最合理的方式排列标题。90%以上的时间,这意味着每个模块只包含它需要的标
但是,创建一个头文件通常是一个好主意,其中包含您正在使用的来自不同库的所有基本头文件或您自己的头文件(具有结构和数据类型定义)。没有万能的解决方案。以最合理的方式排列标题。90%以上的时间,这意味着每个模块只包含它需要的标题。然而,一些程序在模块之间几乎并没有数据结构的隔离,这可能意味着可以使用
#include "alltheheaders.h"
通常,您需要单独的标题 包含超出必要的内容会造成一些潜在的负面影响
这种做法有时很有用:
对于较小的项目,您永远不会注意到差异。然而,一旦您的项目达到了相当大的规模,请坚持这句老话,“只引用直接使用它们的文件中的标题”。如果您有myclass.cpp和myclass.h,并且myclass.h不直接需要特定的头,请在cpp中引用它
这可能需要更多的时间,但最佳实践总是值得的。我只想补充一点,是的,这通常是一个坏主意,但有时也会有用。但是,对于整个项目,从来没有这样做过 例如,我最近编写了一个实用程序来在windows上执行堆栈转储。我打算包括4个常见的标题,所以我(在一个
详细信息
文件夹中,一个我从boost使用中偷来的约定)创建了一个windows.hpp
,其中包括这四个标题。然后,实现可以使用该头轻松地获取必要的函数
虽然它可能不像mega-includes-480-headers头那么重要,但它是由一些常见头组成的一组,非常有用。这里的关键是,它是一个小的相关的头集合,用于代码的一部分。您应该将任何源(*.cpp,*.cc等)文件中包含的头数保持在编译该文件所需的最小值。包括额外的头将增加编译时间。您还应该尝试减少头中包含的数量——您可以通过向前声明类而不是包含它们的头来实现这一点 e、 g.以下代码在标题中包含不必要的include Example.hh
#include "SomeClass.hh"
void SomeFunction(SomeClass const& obj);
class SomeClass;
void SomeFunction(SomeClass const& obj);
Example.cc
#include "Example.hh"
void SomeFunction(SomeClass const& obj)
{
// code here
}
#include "Example.hh"
#include "SomeClass.hh"
void SomeFunction(SomeClass const& obj)
{
// code here
}
它可以写为将include从头文件移动到源文件
Example.hh
#include "SomeClass.hh"
void SomeFunction(SomeClass const& obj);
class SomeClass;
void SomeFunction(SomeClass const& obj);
Example.cc
#include "Example.hh"
void SomeFunction(SomeClass const& obj)
{
// code here
}
#include "Example.hh"
#include "SomeClass.hh"
void SomeFunction(SomeClass const& obj)
{
// code here
}
问题不同,但相关。在今天可用的硬件上,可能还有我较小的程序和模块,我已经很久没有感觉到需要预编译头了。最近我在Microsoft Visual studio 2008上使用MFC做了一个相对较小的五模块项目。MFC对象框架使编译陷入僵局,因此预编译头比不预编译头更快。尽管如此,我还是将预编译数据的读取记录为几秒钟。@mjv:我们主要产品的解决方案包含>350000 LOC。即使使用双四核机器、16 GB RAM和条带RAID磁盘,我们也很难将编译时间保持在调试构建的10分钟以下。在发布版本中,全局优化链接还需要15分钟。如果没有预编译的头文件,我想我们会在这里坐上几个小时。此外,选择性地包含头文件会增加一个自我调节的组件:当您要向文件添加新功能时,如果您正在使用的代码需要添加另一个头文件,则包括,您可以考虑它实际上是否适合于该文件,或者将更好地实现在其他地方。并且它与预编译头文件相融合,因为每当更改任何头文件时,单个头文件都会发生更改。这意味着它必须重新进行预编译(参见Reed的第1点)。我根据工作项目的经验和花在分析构建问题上的大量时间编辑了#1。我的印象是(2)实际上比(1)更浪费程序员时间。我很少坐着等待一个大型项目的完整构建。我经常坐在那里等待部分构建。当然,包括您不使用的内容会增加大量时间,但重新构建不需要的对象文件会增加增量构建时间的倍数。因此,触摸任何标题,实际上你需要一个完整的重建。另一种方法是故意将依赖项弄错,并依赖于记住真正需要重建的内容。不管怎样:啊