如何正确使用stdafx.h?

15

在分离依赖方面,使用 stdafx.h正确方式是什么?

如果我将所有内容都放在其中,那么我的编译速度会非常快,并且我只需要在任何文件中说:

#include "stdafx.h"

有以下注意事项:

  1. 我不再知道哪些文件依赖于哪些头文件。
  2. 它降低了模块化程度,使我的代码可重用性更差。
  3. 没有办法将C++和C的 #include 分开(例如: cstringstring.h),否则需要付出很大代价。(顺带一提,这是否重要?)

如果我什么都不放,就可以很好地组织一切——但是我的编译速度会急剧减慢。

如果我把所有东西 都放进去 ,并且在我的个别文件中包含每个头文件,那么我就能兼顾两种好处,但缺点是现在我必须要关注同步问题。

是否有已知的/被广泛接受的解决方案来解决这个问题?

5个回答

17

不应该把自己的头文件放在 stdafx.h 中,因为你的代码很可能会发生变化,从而导致整个程序重新编译。

通常我会把标准头文件和其他库文件放在里面,例如所有的boost包含文件。


1
同意。将那些在该项目范围内不需要修改的内容放入预编译头文件中。 - Nicol Bolas
我不确定这与什么相关。即使它们是系统头文件,我仍然不知道我的哪些源文件依赖于哪些头文件(我真的需要在每个文件中间接地#include <windows.h>吗?)。因此,它仍将是非模块化的。 - user541686
4
@ Mehrdad,这是使用预编译头文件时需要做出的妥协之一。 - Marlon
@Mehrdad:不要使用PCH编写代码。然后将最常用的外部头文件添加到PCH中。没有问题,预编译头文件纯粹是一种优化。 - Cat Plus Plus
1
这里传播的错误假设是您在解决方案中只能限制为一个预编译头文件。实际上,它最多可以每个翻译单元(源文件)使用一个,并且我已经成功地使用了“每个项目一个”的方法。只有需要包含 <windows.h> 的不可移植部分才需要 PCH。 - MSalters
显示剩余5条评论

8
使用预编译头文件时,应确保项目即使没有PCH也能编译通过(因此将其视为优化,而不是每个TU中包含的替代品)。除此之外,不要把所有东西都放在里面(更重要的是,永远不要放自己项目的头文件——PCH应该只包含那些很少或几乎不会变化的系统库、外部依赖项),而是尽量保持最常用/最大的东西预编译。

1

个人而言,我宁愿编译速度慢一些,也不愿意不知道依赖关系。然而,万事皆有限度。

由于每个项目都有自己的预编译头文件,因此我会将通用的包含文件放在其中。例如,如果一个项目使用了一些 boost 头文件,那么它们很适合放在那里,因为它们将被整个项目使用,并且你不会对它们进行更改。因此,将很少或从不更改的头文件放在预编译头文件中,例如系统或第三方库。

为了提高编译速度,我更倾向于尽可能地使用前向声明,将代码拆分成较小的库,并尝试看看是否可以以一种方式组织代码,使得易变的代码不会影响到其他代码的重新编译。


1
你的编译器可能有一个“显示包含文件”标志。打开它,查找重复的深度嵌套包含层次结构。考虑将最浅的包含文件之一包含到每个这样的深树的头文件中。

0

有条件地包含PCH,然后定义类似于“#define _PRE_COMPILE_”这样的内容。这样原始头文件仍然可见,如果需要,代码就是模块化的。其中一个例子是包括

#ifdef _PRE_COMPILE_
#include "stdafx.h"
#elif
#include <iostream>
#include <cstring>
#endif

在每个源文件的开头包含这个。


1
由于Microsoft的PCH实现方式,将#ifdef放在#include "stdafx.h"之前是无效的。 - Sebastian Redl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接