• 关于VC中的"stdafx.h"


             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文件删除。执行程序时并不需要它们,且随着工程文件的重新建立,它们也自动地重新建立。

    StdAfx.cpp和StdAfx.h是预编译头文件组。先让我们来看看它们的内容:

    //stdafx.h:includefileforstandardsystemincludefiles,
    //orprojectspecificincludefilesthatareusedfrequently,but
    //arechangedinfrequently
    //
    #if!defined(AFX_STDAFX_H__46C144A1_935D_4D36_9A04_F77C1728143A__INCLUDED_)
    #defineAFX_STDAFX_H__46C144A1_935D_4D36_9A04_F77C1728143A__INCLUDED_
    #if_MSC_VER>1000
    #pragmaonce
    #endif//_MSC_VER>1000

    //TODO:referenceadditionalheadersyourprogramrequireshere
    //{{AFX_INSERT_LOCATION}}
    //MicrosoftVisualC++willinsertadditionaldeclarationsimmediatelybeforethepreviousline.
    #endif//!defined(AFX_STDAFX_H__46C144A1_935D_4D36_9A04_F77C1728143A__INCLUDED_)

    //stdafx.cpp:sourcefilethatincludesjustthestandardincludes
    //Example01.pchwillbethepre-compiledheader
    //stdafx.objwillcontainthepre-compiledtypeinformation
    #include"stdafx.h"
    //TODO:referenceanyadditionalheadersyouneedinSTDAFX.H
    //andnotinthisfile

            首先让我们看看StdAfx.h的前两行和最后一行,这被称为头文件保护机制。在这个文件头,首先判断是否定义了AFX_STDAFX_H__46C144A1_935D_4D36_9A04_F77C1728143A__INCLUDED_宏,如果未定义(显然在一开始是这样的),则执行后面的代码:定义这个宏,然后写入头文件的内容,后面再来一个#endif。因此如果这个头文件被#include了两次,则第一次已经定义了AFX_STDAFX_H__46C144A1_935D_4D36_9A04_F77C1728143A__INCLUDED_宏,第二次包括这个头文件的时候就不会满足“该宏未定义”的条件,因此后面的那些头文件内容不会被重复包括一次。这就避免了一个头文件被直接或间接包括多次的错误。至于这个宏的名字,是VC起的,之所以起这么长,就是为了希望不要与用户定义的东西重复,我想不会有哪个程序员会想到在自己的代码中起这么奇怪的名字吧?然后我们可以在这个文件中找到一行:“//TODO:referenceadditionalheadersyourprogramrequireshere”。这是在提示你把项目中要用到的所有头文件的#include宏写到这里,然后再在所有的.cpp文件中使用#include"StdAfx.h",这样做有很多好处:首先是因为方便。当我们要更改某些头文件的包括与否的时候,只需修改StdAfx.h中的内容即可,而不需要更改每个源文件中的#include语句。另外一点,VC中有一种叫做“预编译”的机制:正如我们看到的,StdAfx.cpp中除了注释外就只有一行代码:#include"stdafx.h",当VC在编译的时候,它会先编译这个文件产生一个.pch文件,然后在编译其它有#include"stdafx.h"的文件的时候,只需连接上这个.pch文件即可,而不需要再编译一次stdafx.h中包含的头文件,这会大大提高编译过程的效率(当然,这种技术实现的方法可没有这么简单,我就不再长篇大论了)。至于stdafx.h中的其它内容,就不必管了。

    对于.c文件,由于不能包含stdafx.h,因此可以通过Project settings把它的预编译头设置为“不使用”,方法是:

    • 弹出Project settings对话框
    • 选择C/C++
    • Category选择Precompilation Header
    • 选择不使用预编译头。
  • 相关阅读:
    vue-cli3配置开发环境和生产环境
    vue配置开发环境和生产环境
    js实现div拖拽互换位置效果
    axios用post提交的数据格式
    面试题会被问及哪些?(总结)
    深入理解vue
    nodejs 前端项目编译时内存溢出问题的原因及解决方案
    MUI框架开发HTML5手机APP(一)--搭建第一个手机APP
    关于if省略{}时的一些问题
    函数声明的两种形式的区别
  • 原文地址:https://www.cnblogs.com/secbook/p/2655524.html
Copyright © 2020-2023  润新知