• 【转】C++ 中stdafx.h是什么意思


    转自:http://chunqingu.blog.163.com/blog/static/2275535720115743951140/

    当使用visual c++时,总是包含了头文件stdafx.h,却不知道是干什么用的。

    呵呵,今天查找了相关资料,解释如下:

    当 我们使用appwizard自动生成某些项目时,系统会自动把所需要include的头文件在stdafx.h中先include一下,这样我们只需要直 接include这个stdafx.h文件即可。因为同一个项目中的不同源文件cpp都包含相同的include文件,这样为每个cpp文件都重复 include这些文件就显得很傻了。

    具体在stdafx.h中需要include什么头文件,取决于用户在appwizard中的选择。

    比如:

    #include <afxwin.h>  //MFC core and standard components

    #include <afxext.h> //MFC extensions

    .......

    这样就方便多了,所以stdafx.h时自动生成的。这就使得用户在开发中不必在每个cpp文件中都繁琐的include头文件了,而且维护起来也方便。

    在 生成stdafx.h头文件的同时,也生成stdafx.cpp源文件,该源文件只包含#include "stdafx.h"语句,这是在编译过程中第一个被编译的文件,编译的结果保存在一个名为stdafx.pch的文件里.(扩展名pch表示预编译头文 件.)当visual c++编译随后的每个.cpp文件时,它阅读并使用它刚生成的pch文件.visual c++不再分析windows include 文件,除非用户又编辑了stdafx.h或者stdafx.cpp。

    看了这样的讲解,我马上就实验了一下,自己新建立的一个windows窗口项目,就生成了stdafx.h和stdafx.cpp。

    并且,在主源文件中,就cinlude此头文件stdafx.h。

    以上情况,只在使用appwizard来自动生成项目的时候,才出现,否则,就没有必要include此头文件stdafx.h了。

    补充:

    standard application frame extend

    stdafx.h中没有函数库,只是定义了一些环境参数,使得编译出来的程序能在32位的操作系统环境下运行。
      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文件删除。执行程序时并不需要它们,且随着工程文件的重新建立,它们也自动地重新建立。

     如何使用VC的预编译技术

    一、概念:

    1、预编译:就是编译器首先编译某个文件(称为预编译头文件),然后将这个编译结果保存起来,之后如果有其他源文件include了这个“预编译头文件”的时候,则自动从这个编译结果提取需要的信息进行编译。

    2、预编译结果文件(Precompiled header file):就是那个用来保存已经编译了的符号信息的文件(.PCH作为后缀)

    3、生成预编译结果文件(Create Precompiled header file):我们说源文件A通过文件B“生成预编译结果文件”是指编译A的时候将其中编译B的编译结果保存成预编译结果文件。一般使用向导的话,A文件就 是“stdafx.cpp”,B文件是“stdafx.h”。stdafx.cpp中就一行语句:

    #include “stdafx.h”

    4、使用预编译头(Using precompiled header):我们说某个源文件(a.cpp)通过“stdafx.h”来使用预编译结果是指编译a.cpp的时候,如果a.cpp第一行 include语句是#include “stdafx.h”的话,那么直接取预编译结果文件的结果,不再重新编译”stdafx.h”

    二、向导是怎么做的?

    1、设置“stdafx.cpp”的预编译选项是通过“stdafx.h”文件来“生成预编译结果文件”。

    2、其他源文件的预编译选项设置是通过“stdafx.h”来“使用预编译头”

    三、使用原则?

    1、将相对稳定的头文件(比如CRT,STL,第三方固定的库)全部写在stdafx.h中。(是否使用stdafx.h依赖个人喜好,不过使用stdafx.h可以和向导保持一致)

    2、全部源文件第一行都加#include “stdafx.h”。

    3、一些不能修改的源文件(如果公共的代码,不具备权限修改的代码),设置他的预编译选项是“不使用预编译头”。注意,一定不能是选择“自动生成预编译头”,因为这样会将stdafx.h的结果冲掉(这个不知道是BUG还是设计的问题了,.^_^。)。

    四、Q&A

    Q、为什么不全部使用“自动生成预编译头文件”?

    A、“自动生成预编译头文件”和什么都不用没有什么两样,编译速度没有质的提高。

    Q、手工添加一个新的源文件到项目的时候,经常出现类似错误:

    fatal error C1010: unexpected end of file while looking for precompiled header directive

    A、因为向导缺省的设置是“使用预编译头”,但是你新加的文件并没有在第一行包含“stdafx.h”。解决的方法要么修改成“不使用预编译头”,要么添加一行#include “stdafx.h”

    Q、加stdafx.h和stdafx.cpp总觉得是和编译平台绑定了,不具备移植性?

    A、其实,注意一下stdafx.h的写法就没有问题了。我的解决方案是(stdafx.h的内容):

    –begin of file stdafx.h

    #ifdef _WIN32

    #include “win.h”    // 泛指window下的公共头文件

    #else

    #include “linux.h”    // 泛指linux下的公共头文件

    #endif

    #include “crt.h”      //泛指c标准库

    #include “stl.h”      //泛指STL库

    –end of file

    或者更加简单一点,如果不是VC编译器,那么stdafx.h就什么内容都不写!

     

  • 相关阅读:
    单例模式的几种写法 总结
    TCP的三次握手与四次挥手总结(详解+动图) 面试准备
    向mysql插入表中的中文显示为乱码或问号的解决方法,亲测有用!!
    再论红黑树
    jQuery插件机制
    jQuery高级案例
    jQuery事件绑定与切换
    jQuery动画和遍历
    jQuery基础案例
    DOM操作
  • 原文地址:https://www.cnblogs.com/fzzl/p/2168594.html
Copyright © 2020-2023  润新知