在MFC中,有时需要多个类之间传递信息,一个共通的头文件是个不错的选择。如果在头文件中直接声明一个变量的话,势必会报出一个错误:

  error LNK2005: "struct my_global global_data" (?global_data@@3Umy_global@@A) already defined in MFCApplication1Dlg.obj

  不对呀,我明明是在头文件声明的,不同的文件中的变量应该是同一个啊,怎么还重定义了呢?

  反复查证之后,原来是自己对头文件的理解一直有错误。

  引用一篇好文:http://www.oschina.net/question/253403_44866?sort=time

  摘要部分如下:

  “楼主的问题,是对头文件作用不太了解造成了。头文件本质只是个文本。连源文件都算不上。有些编译器会对.h文件做写特殊化的处理。

  但是希望你理解,.h头 文件自身没有意义,有意义的是#include ,你参考我下面的一个代码例子,不知道你是否能理解,我用C写的,

  C++也基本一样,在使用 #include方面。”

    

//这是一个很简单的程序,就一个main.c函数
#include <stdio.h>
int main(int argc ,char *argv[]){
printf("hello world!\n");
return ;
}
//我把上面修改一下,新生成两个文本文件,printf_hello_world.txt ,return.txt
//printf_hello_world.txt里面的内容就一行
printf("hello world!\n"); //return.txt里面的内容也就一行
return ; //同时修改main.c文件如下
#include <stdio.h>
int main(int argc ,char *argv[]){
#include "printf_hello.world.txt"
#include "return.txt"
}

  "你可以发现,修改后的代码和原始代码运行是一个结果。准确说,对编译器而言,是完全一样的内容。

  #include只是将后面的文件,插入到当前的文本中。其实和.h无关。

  而你将一个函数写在.h里面当多个文件均#include时,则这个函数对于多个文件,再编译器看来,每个文件都存在完全相同的函数

  (只要函数定义 相同就会有冲突)。而C语言或C++,默认对每个函数是可作为外部函数的。此时,连接器就会混乱。究竟连接哪

  个文本(源文件)所编译对应的函数。

  你可以把函数写在头文件里,但需要增加static 前缀。此时这个函数就会在每个#include该头文件的源文件中存在,由于是static,

  对于函数是局部的意思,此时,外部就无法  调用到该函数,最多会出现”找不到该函数的连接错误“而不会说函数重复存在的问题。"

  自然,如果我在头文件中声明变量直接引用的话,就会造成变量重定义的错误。那么该如何正确使用头文件呢?对于函数,我们使用static,对于变量,我们则使用extern。

  具体方法如下:

  在头文件中,添加extern变量:

extern my_global global_data;

  在主对话框中,再次声明该变量:

my_global global_data;

  那么在所有文件中,只要引入头文件,就可以调用该变量了。

  extern的使用是一个基础知识,搞得我昏头昏脑,很是惭愧= = 头文件的正确打开方式则是个意外收获,曰:nice。

MFC学习随笔(2)的更多相关文章

  1. MFC学习随笔(1)

    最近在学习用MFC编写一个简单的界面.其实MFC并不是十分复杂的,经过一段时间的熟悉就可以实现许多基础功能.但是在编写的过程中,经常会遇到林林总总的bug,让人摸不到头脑.今天记录一个过去没有注意过的 ...

  2. MFC 学习之 鼠标移动到Toolbar按钮上显示提示信息(tooltip),状态栏也随之改变

    1.在ResourceView里加入Toolbar资源,命名IDR_TOOLBAR1 2.在主程序的.h文件中加入变量:           CToolBar m_toolbar;CImageList ...

  3. (转) 基于Theano的深度学习(Deep Learning)框架Keras学习随笔-01-FAQ

    特别棒的一篇文章,仍不住转一下,留着以后需要时阅读 基于Theano的深度学习(Deep Learning)框架Keras学习随笔-01-FAQ

  4. C#程序集Assembly学习随笔(第一版)_AX

    ①什么是程序集?可以把程序集简单理解为你的.NET项目在编译后生成的*.exe或*.dll文件.嗯,这个确实简单了些,但我是这么理解的.详细:http://blog.csdn.net/sws8327/ ...

  5. Hive入门学习随笔(一)

    Hive入门学习随笔(一) ===什么是Hive? 它可以来保存我们的数据,Hive的数据仓库与传统意义上的数据仓库还有区别. Hive跟传统方式是不一样的,Hive是建立在Hadoop HDFS基础 ...

  6. JavaScript ES6 数组新方法 学习随笔

    JavaScript ES6 数组新方法 学习随笔 新建数组 var arr = [1, 2, 2, 3, 4] includes 方法 includes 查找数组有无该参数 有返回true var ...

  7. 64位BASM学习随笔(一)

     64位BASM学习随笔(一) Delphi的BASM一直是我最喜爱的内嵌汇编语言,同C/C++的内联汇编相比,它更方便,更具灵活性,由于C/C++的内联汇编仅仅能是或插入式的汇编代码,函数花括号 ...

  8. typeScript学习随笔(一)

    TypeScript学习随笔(一) 这么久了还不没好好学习哈这么火的ts,边学边练边记吧! 啥子是TypeScript  TypeScript 是 JavaScript 的一个超集,支持 es6 标准 ...

  9. MFC学习笔记1---准备工作

    什么是MFC MFC,全称Microsoft Foundation Classes,微软基础类库,顾名思义,是微软的攻城狮们将一些常用的基础的Windows API 函数用C++的形式封装成类,简化程 ...

随机推荐

  1. Android SVN的配置

    关于svn有不错的图文博文,先po一个个人认为很不错的博文:http://ask.android-studio.org/?/article/97 接下来呢呢就是以我个人的思维模式来讲解svn啦: 当然 ...

  2. Linux字符串截取和处理命令 cut、printf、awk、sed、sort、wc

    1. cut [选项] 文件名 -f  列号 #提取第几列(分隔符默认为\t) -d  分隔符 #指定分隔符 例如:cut -f 2 a.txt #截取文件a.txt内容的第二列(列号从1开始) cu ...

  3. My安卓知识2--使用listview绑定sqlite中的数据

    我想在我的安卓项目中实现一个这样的功能,读取sqlite数据库中的数据并显示到某个页面的listview控件中. 首先,我建立了一个Service类,来实现对数据库的各种操作,然后在这个类中添加对数据 ...

  4. PoEdu - C++阶段班【Po学校】- Lesson02_类与对象_第4天

    复习:上节作业讲解 注意点: 设计SetString()的时候,要注意重置原来的空间. char * SetString(const char *str) { _len = strlen(str); ...

  5. iptables示例

    [root@iZ23um2lv3tZ ~]# more /etc/sysconfig/iptables # Generated by iptables-save v1. :: *filter :INP ...

  6. 使用AOP框架所需引入的Jar包

    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w ...

  7. javaweb中实现在线人数统计

    session并不是浏览器关闭时销毁的,而是在session失效的时候销毁下列代码就是监测session创建.销毁 package com.my.count; import javax.servlet ...

  8. CentOS 7 关闭防火墙

    CentOS 7.0默认使用的是firewall作为防火墙 直接关闭防火墙 systemctl stop firewalld.service #停止firewall systemctl disable ...

  9. LocalDB-排序规则:中文乱码; DefaultLanguage

    DefaultLanguage: Set Language 简体中文|us_english SELECT SYSTEM_USER Login SP_DefaultLanguage #Login, 简体 ...

  10. 如何解决oracle数据库过期的情况

    之前用的数据库都是开源的,在另一台电脑上安装的时候,居然有时间限制,只能用30天.安装了好多次都是这样,就这样,三十天一破解.破解方法如下: 不管是快要过期了还是已经过期了,都可以用这个方法. 1.在 ...