有没有办法在 VC++ 中使用预编译的头文件而不需要 stdafx.h?

我有一堆需要编写单元测试的遗留代码.它在任何地方都使用预编译的头文件,因此几乎所有 .cpp 文件都依赖于 stdafx.h,这使得为了编写测试而打破依赖关系变得困难.

I've got a bunch of legacy code that I need to write unit tests for. It uses pre-compiled headers everywhere so almost all .cpp files have a dependecy on stdafx.h which is making it difficult to break dependencies in order to write tests.

我的第一反应是删除所有这些 stdafx.h 文件,这些文件大部分都包含 #include 指令,并根据需要将这些 #include 直接放在源文件中.

My first instinct is to remove all these stdafx.h files which, for the most part, contain #include directives and place those #includes directly in the source files as needed.

这将使得有必要关闭预编译头文件,因为它们依赖于 stdafx.h 之类的文件来确定预编译头文件的停止位置.

This would make it necessary to turn off pre-compiled headers since they are dependent on having a file like stdafx.h to determine where the pre-compiled headers stop.

有没有办法在没有 stdafx.h 依赖的情况下保留预编译的头文件?有没有更好的方法来解决这个问题?

Is there a way to keep pre-compiled headers without the stdafx.h dependencies? Is there a better way to approach this problem?

推荐答案

是的,有更好的办法.

恕我直言,预编译头文件的向导风格"的问题在于,它们鼓励不必要的耦合,并使重用代码变得比应有的困难.此外,使用将所有内容都保留在 stdafx.h"样式编写的代码很容易维护,因为更改任何头文件中的任何内容都可能导致整个代码库每次都重新编译.这会使简单的重构变得很耗时,因为每次更改和重新编译周期都比它应该花费的时间长得多.

The problem, IMHO, with the 'wizard style' of precompiled headers is that they encourage unrequired coupling and make reusing code harder than it should be. Also, code that's been written with the 'just stick everything in stdafx.h' style is prone to be a pain to maintain as changing anything in any header file is likely to cause the whole codebase to recompile every time. This can make simple refactoring take forever as each change and recompile cycle takes far longer than it should.

恕我直言,更好的方法是使用#pragma hdrstop 和/Yc 和/Yu.这使您能够轻松设置使用预编译头文件的构建配置,也可以构建不使用预编译头文件的配置.使用预编译头文件的文件不直接依赖源文件中的预编译头文件本身,这使得它们可以使用或不使用预编译头文件进行构建.项目文件确定哪个源文件构建预编译头文件,每个源文件中的#pragma hdrstop 行确定哪些包含来自预编译头文件(如果使用),哪些直接来自源文件......这意味着当进行维护时,您将使用不使用预编译头文件的配置,并且只有在头文件更改后需要重新构建的代码才会重新构建.在进行完整构建时,您可以使用预编译的头文件配置来加快编译过程.使用非预编译头文件构建选项的另一个好处是,它确保您的 cpp 文件只包含他们需要的内容并包含他们需要的所有内容(如果您使用预编译头文件的向导样式",这将很难做到.

A better way, again IMHO, is to use #pragma hdrstop and /Yc and /Yu. This enables you to easily set up build configurations that DO use precompiled headers and also build configurations that do not use precompiled headers. The files that use precompiled headers don't have a direct dependency on the precompiled header itself in the source file which enables them to be build with or without the precompiled header. The project file determines what source file builds the precompiled header and the #pragma hdrstop line in each source file determines which includes are taken from the precompiled header (if used) and which are taken directly from the source file... This means that when doing maintenance you would use the configuration that doesn't use precompiled headers and only the code that you need to rebuild after a header file change will rebuild. When doing full builds you can use the precompiled header configurations to speed up the compilation process. Another good thing about having the non-precompiled header build option is that it makes sure that your cpp files only include what they need and include everything that they need (something that is hard if you use the 'wizard style' of precompiled header.

我在这里写了一些关于它是如何工作的:http://www.lenholgate.com/blog/2004/07/fi-stlport-precompiled-headers-warning-level-4-and-pragma-hdrstop.html (忽略有关/FI 的内容),我有一些示例项目使用 #pragma hdrstop 和/Yc/Yu 方法构建:http://www.lenholgate.com/blog/2008/04/practical-testing-16---修复-a-timeout-bug.html .

I've written a bit about how this works here: http://www.lenholgate.com/blog/2004/07/fi-stlport-precompiled-headers-warning-level-4-and-pragma-hdrstop.html (ignore the stuff about /FI) and I have some example projects that build with the #pragma hdrstop and /Yc /Yu method here: http://www.lenholgate.com/blog/2008/04/practical-testing-16---fixing-a-timeout-bug.html .

当然,从向导风格"的预编译标头使用转变为更受控制的风格通常并非易事......

Of course, getting from the 'wizard style' precompiled header usage to a more controlled style is often non-trivial...

相关文章