• 对C++文件组织及全局对象的理解的修正


    关于头文件和源文件的文件类型

    头文件定义函数、类、变量的声明,告诉编译器这个项目中有哪些对象,源文件才是实现代码,为了在模块间共享,一般都是把声明和实现分开,需要哪个模块时就include那个模块的h文件。

    编译器对文件类型是没有严格要求的,源文件和头文件名也不需要严格保持一致,但是为了直观,便于阅读,习惯上用cpp作为源文件,h作为头文件,文件名保持一致。

    需要注意的是,h中声明的函数,cpp不需要包含这个h也能编译,似乎编译器能过根据函数定义在所有模块中自动寻找实现代码,只要保证项目中函数名称唯一就可以了。而类、结构等cpp文件必须包含h,因此每个cpp包含自己的h还是必须的。

    关于模块包含

    由于声明和实现分开,每个cpp必须include自己的h文件。加上所有cpp必须引用预编译头。

    #include "stdafx.h"

    这时会引发一些混乱,一般都希望将相对不变的公共模块的h文件include到stdafx.h中,这样可以减少编译时间,也方便维护。但是假如有一个公共类模块的h文件被包含在stdafx.h中,如果该类的cpp同时包含了stdafx.h和自己的h文件,就会出现重复定义的错误。应该把cpp里去掉include自己的h文件,也可以使用下面的方法。

    防止交叉重定义

    在每个cpp文件中加上以下代码

    VC6中:
    #if !defined(XXXX_XXXX) //xxxx部分使用文件名和特殊字母定义,以作区别,且必须大写
    #define XXXX_XXXX
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    .......//这里变量和函数声明部分
    #endif

    VS2008中简单了:

    #pragma once

    连接时全局对象和extern以及重定义的问题

    虽然上面的方法可以避免重定义,但也只是针对单一模块来说的,由于编译时是单个模块分别编译生成obj文件的,通过上面两种方式处理编译是没问题了,因为每处理一个cpp时是不考虑其他cpp有些什么东西的,但是在链接时链接器发现了多同名对象而出错。比如说在stdafx.h中定义了一个int a;,那么所有cpp都会包含它,使得整个项目中所有obj都存在一个int a,连接时因为发现多个定义而报错。

    解决方法是:

    对于全局对象(包括普通变量),在stdafx.h中以extern修饰定义(也可以单独把所有全局对象以extern修饰写在一个h文件中再包含到stdafx.h),然后在任意一个cpp中声明,只在一个cpp中定义一次即可,其他cpp就可以使用该对象了。如此,连接器在遇到使用该对象时会在所有obj定位该对象。一般把全局对象的定义写在主程序所在cpp中。

    关于全局函数,模块中如要调用一个全局函数必须包含了该函数的h文件,因此函数所在h文件包含到stdafx.h文件中就形成了全局函数,由于函数不是不是对象实例,不会出线连接错误。

  • 相关阅读:
    在桌面建立快捷方式 Mr
    在窗口中显示一幅 JPG 图象 Mr
    【转载】COM组件设计与应用(一)——起源及复合文件 Mr
    【转载】COM组件设计与应用(二)——GUID和接口 Mr
    关于在Win7 SP1操作系统下编译的ADO应用程序不能在比Win7 SP1版本低的操作系统上运行,微软给出的解释和解决方案 Mr
    Vue UI图形化项目管理使用
    vue+eldialog提交校验
    获取当前日期前一个月日期与天数数组
    element输入框只能输入数字或小数保留两位小数
    vue+ DatePicker日期的加减
  • 原文地址:https://www.cnblogs.com/CodeBlove/p/1658347.html
Copyright © 2020-2023  润新知