用MFC制作的工程由很多文件构成,它不能象一般C++程序那样随意在类外定义全局变量,在这里要想定义能被工程内多个文件共享的全局变量和函数必须用一些特殊方法才行。实际上有多种方法可以实现,这里只介绍两种方法。

一、在应用程序类中定义

用MFC生成的工程中都有一个名为CxxxApp的类,它派生于CWinApp类。这个类主要进行程序的初始化,生成文档、视图对象等工作。我们可以把需要全局访问的变量和函数定义为这个类的成员变量和成员函数,就可以实现全局访问了。

从严格意义上讲,这种变量和函数并不是全局的,因为它仍然只是类中的成员,只是由于我们很容易获得CxxxApp类的指针,所以我们可以在文档、视图、对话框以及各种自定义类中访问到它们,达到与全局变量类似的效果。访问时用函数“AfxGetApp()”获得CxxxApp类的指针,用“AfxGetApp()->成员”访问变量或函数。

例:

Test.h:(应用程序类头文件)

class CTestApp : public CWinApp 

public: 
int x; //全局变量 
int f(int y); //全局函数 
………… 
};

Test.cpp:(应用程序类程序文件)

int CTestApp::f(int y) //全局函数定义 

y++; 
return y; 
}

定义在CTestApp类中的变量和函数可以在其它类中被访问。比如在视图的某函数中要访问变量x和函数f():

void CTestView::xyz() 

CTestApp *app = (CTestApp *)AfxGetApp(); //生成指向应用程序类的指针 
app->x = 0; //访问变量x 
int z = app->f(1); //访问函数f() 
………… 
}

这样,变量x和函数f()可以视作为全局的。

用这种方法实现的全局变量和全局函数虽比较简单,但也有缺点,一是访问不太方便,每次都需要获取应用程序类的指针;再就是把一些与应用程序类本身无关的变量和函数放在里面,使这个类看上去怪怪的,破坏了类的封装。

二、用静态变量和静态函数实现

很喜欢API函数的那种调用方法,不论在哪个类中只要用“::API函数”就可以调用了。合理利用静态类型(static)可以实现与此相似的全局变量和全局函数。

静态变量和静态函数有如下性质:

若在一个类中用关键字static声明数据成员,则这个数据成员就只存在一个拷贝,无论该类创建了多少个实例,它始终只存在一个,即使该类的实例一个也没创建,它也存在。

若在一个类中用关键字static声明函数,该函数可以用“类名::函数名”方式访问,无需引用该类的实例,甚至这个类的实例可以不存在。

利用这个性质实现的全局变量和函数使用起来很方便。

值得注意的是,全局变量和全局函数最好集中封装,不要在文档、视图等类内部定义,这样用起来才有全局的感觉。

例:

1、添加一个没有基类的新类,设类名起为CPublic,姑且称之为公用类

单击“Insert”菜单下的“New Class”命令,选择“Class type”为“Generic Class”,在“Name”栏中填入类名“CPublic”,单击“OK”,则新类建立完毕。

2、包含公用类的头文件,使各个类都能访问它

CPublic的头文件应包含在应用程序类的头文件中,这样在其它类中引用CPublic类时就不需要再包含了。

Test.h:(应用程序类头文件)

#include "Public.h" //包含公用类头文件

class CTestApp : public CWinApp 

………… 
};

3、在公用类中定义全局变量和全局函数,均使用static修饰,静态变量还必须在类外定义和初始化

Public.h:(公用类头文件)

class CPublic 

public: 
CPublic(); 
virtual ~CPublic();

public: 
static int x; //全局变量 
static int time; //全局变量 
static int f(int y); //全局函数 
………… 
}

在公用类中对静态变量进行初始化和定义函数体:

Public.cpp:(公用类程序文件)

int CPublic::x = 0; //初始化全局变量 
int CPublic::time; //定义全局变量

CPublic::CPublic() 
{

}

CPublic::~CPublic() 
{

}

int CPublic::f(int y) //全局函数,这里不要再加static 

y++; 
return y; 
}

4、全局量的使用

使用变量:CPublic::变量名

使用函数:CPublic::函数()

如在视图的某函数中访问变量x和函数f():

void CTestView::xyz() 

CPublic::x = 0; //访问变量x 
CPublic::time = CPublic::f(1); //访问函数f() 
………… 
}

在其它类中访问x、time和f()的方法与此相同。

5、几点注意:

① 由于静态量可独立于类存在,不需要生成CPublic类的实例。

② 静态数据成员的定义和初始化必须在类外进行,如例中x的初始化;变量time虽然没有初始化,但也必须在类外进行定义。由于没有生成CPublic类的实例,所以它的构造函数和析构函数都不会被执行,在里面做什么工作都没有什么意义。

③ 如果静态函数需要访问CPublic类内的变量,这些变量也必须为静态的。因为非静态量在不生成实例时都不会存在。 如:

class CPublic 

public: 
int x; //内部变量 
static int f(int y) //全局函数 

x++; 
return x; 
}; 
………… 
};

这里x虽为类内成员,但如果不生成CPublic类的实例,就会出现函数f()存在,而变量x不存在的问题。

总之,用没有实例的类管理全局量是一个不错的选择,它具有集中管理,使用方便的好处。当然,除非特别必要,全局量还是少用为好,一个好的编程者决不会随意滥用全局量的,一个封装做得不好的程序,在修改维护时会让你吃足苦头

MFC中全局变量的定义及使用的更多相关文章

  1. VUE中全局变量的定义和使用

    目录 VUE中全局变量的定义和使用 1.工作中遇到的两类问题 1.1 状态值(标志) 1.2 传递字段 2.解决方法 2.1 VUEX 2.2 使用全局变量法管理状态与字段值 3.具体实现 3.1创建 ...

  2. QT中全局变量的定义

    多的就不说了,本来就是一个简单地内容,只是不会的话会很头疼 我们首先新建两个文件,文件名可以自定义,我们在这里定义为variate.h 和 variate.cpp 当然了,后缀是不能变的. 和函数一样 ...

  3. 解决C/C++语言中全局变量重复定义的问题

    前言 今天,在整理自己的代码的时候,考虑到我写的代码从一至终都是在一个cpp文件里面.于是,想把自己的代码中的各个模块分离开来,以便更好地阅读和管理. 遇到的问题 我的做法是: 宏定义.结构体定义.函 ...

  4. VC/MFC中为程序定义全局快捷键

    VC 2010-05-01 18:01:34 阅读287 评论0 字号:大中小 订阅 1.注册快捷键 在初始化函数,如OnInitDialog() 注册快捷键,代码如下: #define HotKey ...

  5. javascript中全局变量的定义

    首先确实简单,在js脚本的函数外面使用. 但是要注意点: 不能写到jquery的框框代码里面,之前粗心放到$(function(){ })里面去了. <script type="tex ...

  6. C语言全局变量的定义与声明

    C语言中全局变量的定义与声明困扰着许多C语言初学者.本文讲述了全局变量定义与声明的用法,而且本为也将阐述这种用法的内在原理.我们先从两个错误例子引入,以下两个例程都在vc6.0平台上测试. 两种错误例 ...

  7. 在VC/MFC中嵌入Google地图——图文并茂

    近期须要实验室须要将在无人机地面站中嵌入地图,在网上找了非常多资料,最终有些眉目了, 首先.做这个须要用到的知识有.MFC控件.MFC类库.JavaScript脚本语言.Google API.Goog ...

  8. MFC 中线程传递CString 是不安全的 转

     MFC 中线程传递CString 是不安全的       在MFC中,向线程传递CString变量参数时,很容易犯一个错误,就是使用一个超出生存期的变量,在主函数中定义的CString变量是局部变量 ...

  9. MFC中线程相关知识

    MFC中把线程分为两种类型,UI线程和工作者线程. MFC中启动一个线程的最好方法是调用AfxBeginThread,有两个版本,一个用于启动Ui线程,另外一个用于启动工作者线程.在MFC程序中,只有 ...

随机推荐

  1. OC - 10.使用Quartz2D绘制个性头像

      效果图 将一张图片剪切成圆形 在图片周围显示指定宽度和颜色的边框 实现思路 效果图中主要由不同尺寸的两大部分组成 蓝色的背景区域,尺寸等于图片的尺寸加上边框的尺寸 图片区域,尺寸等于图片的尺寸 绘 ...

  2. UIViewController的View显示在导航栏下面如何解决?

    ios7之前的版本中UIViewController中的view在显示后会自动调整为去掉导航栏的高度的,控件会自动在导航栏以下摆放. 在iOS7中UIViewController的wantsFullS ...

  3. 外边距叠加collapsing-margin

    原载:Smallni | http://www.smallni.com/collapsing-margin/ 恩,margin叠加一直是个问题,也是我们一直会遇到的问题,很久以前就想把这个知识点整理下 ...

  4. MySQL学习-常用命令整理

    Eyes are more eloquent than lips. “眉目传情胜于甜言蜜语” 整理了一下自己遇到并且经常用到的MySQL命令,虽然官方文档上有很详细的解释,不过自己还是在这里记录一下, ...

  5. Java学习----你的选择是什么-条件结构

    import java.util.Scanner; public class Student { public static void main(String[] args) { byte money ...

  6. jquey复选框三级分类关联一二级分类

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Category_Manag ...

  7. 面向对象设计模式之Interpreter解释器模式(行为型)

    动机:在软件构建过程中 ,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化.在这种情况下,将特定领域的问题表达为某种语法规则的句子,然后构建一个 ...

  8. JS indexOf() lastIndexOf()与substring()截取字符串的区别

    1. String.IndexOf 方法 (value[,startIndex]) value:要查找的 Unicode 字符. 必选项startIndex:搜索起始位置.  可选项 不写从开头查找 ...

  9. 用OpenGL简单编写的一个最简单贪吃蛇游戏

    刚学OpenGL的时候,写的一个最简单的贪吃蛇游戏代码 如下: //贪吃蛇游戏 #include<stdio.h> #include<stdlib.h> #include< ...

  10. 『Python』爬行搜索引擎结果获得指定主机二级域名及IP信息

    0x 00 前言 前天自己在玩的时候,自己通过百度搜索主机的二级域名感觉好麻烦,自已要一页页的去翻 而且人工识别是否是重复的二级域名也够蛋疼的,正好最近在学正则表达式,权当练手了 0x 00 代码 # ...