预编译头文件

33

我有一个示例项目(不是我的),它是使用Visual C++ 6编写的。我正试图将其转换为Visual Studio 2008。

旧项目正在使用预编译标头。现在问题是:

  1. 什么是预编译标头?

  2. 由于旧项目正在使用预编译标头,因此我也将在Visual Studio 2008中使用它们(新项目)。但是我会遇到错误,说"Did you forget to include stdafx.h",为了解决这个问题,我在每个源文件中都包含"stdafx.h"。那很完美。但是旧项目并没有在每个文件中包含“stdafx.h”?那么如何选择不在每个源文件中包括"stdafx.h"。因为不是每个源文件都需要在"stdafx.h"中定义的包含文件,只有少数需要。该怎么办呢?

如何将某些文件排除在使用预编译标头之外?

3个回答

57

预编译头是什么?

通常,C++源文件包括来自外部库的头文件。在Windows中,你需要包含windows.h。这些头文件可能非常大,并且处理它们需要一定的时间。每次编译C++文件时,编译器必须读取和处理这些头文件中的成千上万行代码。但外部库不会改变,如果您只处理一次并保存结果,则可以节省大量时间。

预编译头其实就是一堆经过处理成中间形式的头文件,稍后可以由编译器再次使用。

Visual C++中的预编译头

在Visual C++中,习惯上将所有不变的头文件包含在stdafx.h中。然后,您需要在编译stdafx.cpp时指示编译器创建预编译头文件stdafx.pch,该文件仅包含stdafx.h。如果您想在另一个.cpp文件中使用预编译头,则必须将stdafx.h作为第一个包含文件,并指示编译器使用stdafx.pch作为预编译头。

如果您遇到有关未包含stdafx.h的错误,则只需指示编译器不对该特定源文件使用预编译头文件(或者您可以包括stdafx.h)。

单个源文件的预编译头设置

Visual C++允许您控制整个项目和单个文件的编译器设置。要访问单个属性,您需要在解决方案资源管理器中选择源文件,右键单击并从上下文菜单中选择属性。预编译头选项位于配置属性 => C/C++ => 预编译头中。如果您修改了这些设置,则通常希望对所有配置(例如DebugRelease)进行修改。

当您使用预编译头文件时,您将为整个项目设置一个设置,指示编译器使用 stdafx.pch 作为预编译头文件。 stdafx.cpp 将具有单独的设置,指示编译器生成 stdafx.pch,如果您有一些源文件不包括 stdafx.h,则可以在这些文件上设置单独的设置以不使用预编译头文件。


6
当您编译代码时,编译器必须查看所有 #included 头文件,以了解如何编译您的 .cpp 文件中的代码。
使用大型项目(或使用类库(例如 MFC)的项目)这些头文件可能会变得非常庞大,因此编译时间也会很长。
由于这些头文件大多数情况下并不会经常更改(如果有的话),因此您可以让编译器“预编译”它们 - 它会处理它们并将其状态保存到预编译头文件中。下次编译时,它就不需要再次读取和编译所有这些头文件,因此速度要快得多。
Visual Studio 中的一个要求是,如果您使用预编译头文件,则必须将其包含在项目的每个文件中。
如果项目很小或者您不经常构建它,则可以禁用“预编译头文件”选项(在项目设置中)。这将应用于整个项目。唯一的影响是可能会导致编译速度变慢。或者保留该选项并在每个文件中的第一个位置添加 #include "stdafx.h"。

错了,为什么在MSVC6中我不需要在每个文件中包含预编译头文件??? - akif
他(Jason Williams)是正确的。stdafx.h 只会在那些没有使用 stdafx.h 中包含的任何内容(例如,Windows 头文件)的文件中不被包含。否则,请仔细查看,stdafx.h 可能会通过其他间接包含方式被包含进来。 - Aamir
@Jason在陈述“[o]ne requirement in Visual Studio is that if you use a precompiled header, it must be included in every file in the project.”时是错误的。这是错误的。您可以选择加入或排除单个文件(缺少/Y开关);如果不能这样做,那么在项目中混合C和C++源文件将会很困难。 - vladr

2
  1. 请参阅MSDN
  2. 通常情况下,您需要在每个cpp文件中包含"stdafx.h"。这样做的整个目的是它们被预编译,您不必担心某些具体文件中没有使用所有文件。

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