MFC中全局变量的定义及使用

MFC中全局变量的定义及使用

用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不存在的问题。

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

(0)

相关推荐

  • C++基础知识篇:C++ 存储类

    存储类定义 C++ 程序中变量/函数的范围(可见性)和生命周期.这些说明符放置在它们所修饰的类型之前.下面列出 C++ 程序中可用的存储类: auto register static extern m ...

  • link script(链接器ld吃的文件)中使用宏定义的解决方案

    问题:工作中遇到一个需求:需要在ld script中使用类似C语言的define等宏定义来做一些判断和替换 实验: 1:理论上*.c中都能用,是否gcc/ld也支持在ld script中直接用宏呢,结 ...

  • 你真的了解高中数学中切线的定义吗?

        关于切线的概念好像都是直接拿来用的,教科书上并没有标注切线的定义,很多同学知道切线就是和函数图像有一个交点的直线,但是事实并非如此,切线也可能与函数图像交于两个或多个点,因此我个人强烈建议高中 ...

  • GD&T中要素的定义详解

    在实际产品设计.应用中,不论是设计人员,还是工艺.品质人员,对于一些尺寸要求的术语,都是按照自己的理解来说明,这样就会存在一个问题,每个人有每个人的理解,有自己的一套说法,但是,整个团队里面同一个零件 ...

  • 软件测试中的性能测试定义

    什么是软件性能: 软件性能是软件的一种非功能特性,它关注的不是软件是否能够完成 特定的功能,而是在完成该功能时展示出来的及时性. 一般性能测试是在功能测试完成之后 性能测试定义: 指通过自动化的测试工 ...

  • ABAQUS切削分析中材料的定义

    切削过程涉及到弹性力学,塑性力学.热力学以及损伤力学等相关学科领域,初学者在使用ABAQUS做切削分析时,很难处理材料属性(material property)问题.即使是方法正确.操作正确,也得不到 ...

  • 【数控刀具选用指南2】金属切削过程中的基本定义(下)

    在<[数控刀具选用指南]金属切削过程中的基本定义(上)>中,我们了解了金属切削过程中的切削运动和切削用量.本期将继续介绍有关金属切削过程的基础知识,请大家和小编一起来看看吧~ (本篇选自& ...

  • 【数控刀具选用指南1】金属切削过程中的基本定义(上)

    ☞ 这是金属加工(mw1950pub)发布的第13144篇文章 编者按 切削刀具是数控加工过程中必不可少的一环,选用合适的刀具是影响切削效率和质量的关键要素.实践证明,通过正确地选择和使用刀具来提高生 ...

  • 飞行员想知道:飞行程序中的这些定义

    机场标高 aerodrome elevation 机场标高大家应该很熟悉,但不少人对它是怎么确定的不太清楚,有的人还以为就是机场基准点(ARP)的标高. 事实上,机场标高是着陆区中最高点的标高,并不是 ...