一、 预编译头文件c++
做用:提升编译效率。预编译头文件(扩展名为.PCH),是为了提升编译效率而使用的一种方法,把一个工程中较稳定的代码预先编译好放在一个文件(.PCH)里.避免每次编译时去从新编译没有修改的全部文件,这些预先编译好的代码能够是任何的C/C++代码。函数
为何须要预编译头文件?一言以蔽之:提升编译速度.通常地,编译器以文件为单位编译,若是修改了工程中的一个文件则全部文件都要从新编译,包括头文件里的全部东西(例如Macro宏,Preprocessor预处理),而VC程序中,这些头文件中所包括的东西每每是很是大的,编译之将占很长的时间.但它们又不常被修改,是较稳定的,为单独的一个小文件而从新编译整个工程的全部文件致使编译效率降低,所以引入了.PCH文件.ui
要使用预编译头文件,必须指定一个头文件(.H),它包含咱们不会常常修改的代码和其余的头文件,而后用这个头文件(.H)来生成一个预编译头文件(.PCH)。VC默认的头文件就是StdAfx.h,由于头文件是不能编译的,因此咱们还须要一个.CPP文件来做桥梁,VC默认的文件为StdAfx.cpp,这个文件里只有一句代码就是:#include "StdAfx.h".接下来要用它生成.PCH文件。component
默认的预编译头文件StdAfx.h及CPP文件StdAfx.cpp能够是任何名字的.缘由很简单.但若是你要这样作就要记得修改相应的Project->setting...下的几个预编译指令(/Yc,/Yu,/Yx,/Fp)的参数。htm
举一个简单的例子:一个c++工程包含四个文件,pch.h、pch.cpp和Audio.h、Audio.cpp.头文件pch.h里面的内容包含不会常常变化的c++代码和其余稳定的头文件。Pch.cpp里面就一句话#include “pch.h” .为了说明预编译头文件能够是任意的,而不是vc默认的stdafx.h,我这里使用pch.头文件做为预编译头文件。因此,将pch.cpp设置为create产生预编译头文件开发
将其余的cpp文件设置为use使用预编译头文件get
所谓的预编译头就是把一个工程中的那一部分代码,预先编译好放在一个文件里(一般是 以.pch为扩展名的),这个文件就称为预编译头文件这些预先编译好的代码能够是任何的 C/C++代码,甚至是inline的函数,可是必须是稳定的,在工程开发的过程当中不会 被常常改变。若是这些代码被修改,则须要从新编译生成预编译头文件。注意生成预编 译头文件是很耗时间的。同时你得注意预编译头文件一般很大,一般有6-7M大。注意及 时清理那些没有用的预编译头文件。 也许你会问:如今的编译器都有Time stamp的功能,编译器在编译整个工程的时候,它 只会编译那些通过修改的文件,而不会去编译那些从上次编译过,到如今没有被修改过 的文件。那么为何还要预编译头文件呢?答案在这里,咱们知道编译器是以文件为单 位编译的,一个文件通过修改后,会从新编译整个文件,固然在这个文件里包含的全部 头文件中的东西(.eg Macro, Preprocesser )都要从新处理一遍。VC的预编译头文件 保存的正是这部分信息。以免每次都要从新处理这些头文件。 编译器
预编译头的使用: 要使用预编译头,咱们必须指定一个头文件,这个头文件包含咱们不会常常改变的 代码和其余的头文件,而后咱们用这个头文件来生成一个预编译头文件(.pch文件) 想必你们都知道 StdAfx.h这个文件。不少人都认为这是VC提供的一个“系统级别”的 ,编译器带的一个头文件。其实不是的,这个文件能够是任何名字的。咱们来考察一个 典型的由AppWizard生成的MFC Dialog Based 程序的预编译头文件。(由于AppWizard 会为咱们指定好如何使用预编译头文件,默认的是StdAfx.h,这是VC起的名字)。咱们 会发现这个头文件里包含了如下的头文件:io
#include // MFC core and standard components编译
#include // MFC extensions
#include // MFC Automation classes
#include // MFC support for Internet Explorer 4 Common Controls
这些正是使用MFC的必须包含的头文件,固然咱们不太可能在咱们的工程中修改这些头文 件的,因此说他们是稳定的。 那么咱们如何指定它来生成预编译头文件。咱们知道一个头文件是不能编译的。因此我 们还须要一个cpp文件来生成.pch 文件。这个文件默认的就是StdAfx.cpp。在这个文件 里只有一句代码就是:#include “Stdafx.h”。缘由是理所固然的,咱们仅仅是要它能 够编译而已也就是说,要的只是它的.cpp的扩展名。
如下是注意事项:
一、若是使用了/Yu,就是说使用了预编译,咱们在每一个须要使用预编译头文件的.cpp文件的最开头,我强调一遍是最开头,包含你指定产生pch文件的.h文件(默认是stdafx.h)否则就会有问题。缘由:编译器经过一个头文件stdafx.h来使用预编译头文件。stdafx.h这个头文件名是能够在project的编译设置里指定的。编译器认为,全部在指令#include "stdafx.h"前的代码都是预编译的,它跳过#include "stdafx. h"指令,使用projectname.pch编译这条指令以后的全部代码。(在编译的时候,在#include "stdafx. h"前面的语句都不予以编译)
所以,全部的CPP实现文件第一条语句都是:#include "stdafx.h"。
二、若是你把pch文件不当心丢了,编译的时候就会产生不少的不正常的行为。根据以上 的分析,你只要让编译器生成一个pch文件。也就是说把 stdafx.cpp(即指定/Yc的那个 cpp文件)重新编译一遍。固然你能够傻傻的 Rebuild All。简单一点就是选择那个cpp 文件,从新编译就便可。否则但是很浪费时间的哦。
三、在其余的头文件里也include 预编译头文件。假设你的其余头文件也include了预编译头文件, 若是别人引用你的这个头文件又没有设置成预编译头文件, 那引用你头文件的这我的就煎熬了。缘由:因为你用到的.h文件里include了预编译头文件,他在他自己的project里,vs可以判断的出他是预编译头,也能找的到须要的pch,pdb文件。因此对写这个.h文件的人没影响。可是你做为他的客户,你工做在你的project下,你include了他的h头文件,而这时vs判断不出他的头文件里include的stdafx是预编译头文件,作普通文件编。那可想而知,他的stdafx里若是有import外面大型的库(如inventor的tlb,很是慢,咱们犯了这个错),那编译速度简直是煎熬。最要命的是,之后你作任何简单的修改都要重编,这和预编译解决的问题刚好相反了。
四、vc默认状况下使用预编译头(/Yu),不明白的在加入新.h文件后编译时总出现fatal error C1010:在查找预编译头指令时遇到意外的文件结尾的错误。解决方法是在在include头文件的地方加上#include "stdafx.h",或者打项目属性,找到“C/C++”文件夹,单击“预编译头”属性页。修改“建立/使用预编译头”属性为“不使用预编译头”。
下面给出一个使用预编译头文件的操做步骤, 享受一下预编译头文件给咱们带来的编译速度的提高:
1) 添加一个stdafx.h文件(名字随便取, 这里用了VS默认提供的名称), 在这个.h文件里include要使用的头文件(通常是外部的库, 本身写的不常变的头文件也能够加进来)
2) 添加一个stdafx.cpp文件, 并include "stdafx.h"
3) 项目属性-->c/c++-->Precompiled设置为Use Precompiled Header, stdafx.h
4) stdafx.cpp属性-->c/c++->Precompiled设置为Create Precompiled Header, stdafx.h
5) done!
Windows和MFC的include文件都很是大,即便有一个快速的处理程序,编译程序也要花费至关长的时间来完成工做。因为每一个.CPP文件都包含相同的include文件,为每一个.CPP文件都重复处理这些文件就显得很傻了。 为避免这种浪费,AppWizard和VisualC++编译程序一块儿进行工做,以下所示: ◎AppWizard创建了文件stdafx.h,该文件包含了全部当前工程文件须要的MFCinclude文件。且这一文件能够随被选择的选项而变化。 ◎AppWizard而后就创建stdafx.cpp。这个文件一般都是同样的。 ◎而后AppWizard就创建起工程文件,这样第一个被编译的文件就是stdafx.cpp。 ◎当VisualC++编译stdafx.cpp文件时,它将结果保存在一个名为stdafx.pch的文件里。(扩展名pch表示预编译头文件。) ◎当VisualC++编译随后的每一个.cpp文件时,它阅读并使用它刚生成的.pch文件。VisualC++再也不分析Windowsinclude文件,除非你又编缉了stdafx.cpp或stdafx.h。 这个技术很精巧,你不这么认为吗?(还要说一句,Microsoft并不是是首先采用这种技术的公司,Borland才是。)在这个过程当中你必须遵照如下规则: ◎你编写的任何.cpp文件都必须首先包含stdafx.h。 (等待考察) ◎若是你的工程文件里的大多数.cpp文件都须要某些.h文件,顺便将它们加在stdafx.h文件里面,而后预编译stdafx.cpp。 ◎因为.pch文件具备大量的符号信息,它是你的工程文件里最大的文件。 若是你的磁盘空间有限,你就但愿能将这个你从没使用过的工程文件中的.pch文件删除。执行程序时并不须要它们,且随着工程文件的从新创建,它们也自动地从新创建。