c++ 静态成员函数js函数内修改全局变量量

在MFC下如何定义全局变量和全局函数_百度经验
&&&&&&&&&电脑软件在MFC下如何定义全局变量和全局函数
百度经验:jingyan.baidu.com
初学MFC的注意了,这是一篇很好的文章,以前在网上看到的,觉得很好就保存了下来,现在分享给大家:(由于出处找不到,暂标为原创)
& &用MFC制作的工程由很多文件构成,它不能象一般C++程序那样随意在类外定义全局变量,在这里要想定义能被工程内多个文件共享的全局变量和函数必须用一些特殊方法才行。实际上有多种方法可以实现,这里只介绍两种方法。
一、在应用程序类中定义  用MFC生成的工程中都有一个名为CxxxApp的类,它派生于CWinApp类。这个类主要进行程序的初始化,生成文档、视图对象等工作。我们可以把需要全局访问的变量和函数定义为这个类的成员变量和成员函数,就可以实现全局访问了。  从严格意义上讲,这种变量和函数并不是全局的,因为它仍然只是类中的成员,只是由于我们很容易获得CxxxApp类的指针,所以我们可以在文档、视 图、对话框以及各种自定义类中访问到它们,达到与全局变量类似的效果。访问时用函数“AfxGetApp()”获得CxxxApp类的指针,用 “AfxGetApp()-&成员”访问变量或函数。  例:  Test.h:(应用程序类头文件)class CTestApp : public CWinApp + Q+ } public:   //全局变量  int f(int y); //全局函数 ) X &s+ s' N+ U  …………  Test.cpp:(应用程序类程序文件)int CTestApp::f(int y) //全局函数定义{   定义在CTestApp类中的变量和函数可以在其它类中被访问。比如在视图的某函数中要访问变量x和函数f():void CTestView::xyz(){  CTestApp *app = (CTestApp *)AfxGetApp(); //生成指向应用程序类的指针 /  app int z = app-&f(1); //访问函数f() 0 R,}  这样,变量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: //全局变量 % v //全局变量 #static int f(int y); //全局函数
}   在公用类中对静态变量进行初始化和定义函数体:  Public.cpp:(公用类程序文件)int CPublic::x = 0; //初始化全局变量 int CPublic:: //定义全局变量 CPublic::CPublic() {} CPublic::~CPublic() { }int CPublic::f(int y) //全局函数,这里不要再加static { y++; 4 } 3 O2 V% Z6 r+ r( k! L  4、全局量的使用  使用变量:CPublic::变量名6 H)  使用函数: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类内的变量,这些变量也必须为静态的。因为非静态量在不生成实例时都不会存在。  这里x虽为类内成员,但如果不生成CPublic类的实例,就会出现函数f()存在,而变量x不存在的问题。  总之,用没有实例的类管理全局量是一个不错的选择,它具有集中管理,使用方便的好处。当然,除非特别必要,全局量还是少用为好,一个好的编程者决不会随意滥用全局量的,一个封装做得不好的程序,在修改维护时会让你吃足苦头。
百度经验:jingyan.baidu.comVC++经验内容仅供参考,如果您需解决具体问题(尤其法律、医学等领域),建议您详细咨询相关领域专业人士。作者声明:本篇经验系本人依照真实经历原创,未经许可,谢绝转载。投票(3)已投票(3)有得(0)我有疑问(0)◆◆说说为什么给这篇经验投票吧!我为什么投票...你还可以输入500字◆◆只有签约作者及以上等级才可发有得&你还可以输入1000字◆◆如对这篇经验有疑问,可反馈给作者,经验作者会尽力为您解决!你还可以输入500字相关经验001140热门杂志第1期你不知道的iPad技巧3724次分享第1期win7电脑那些事6566次分享第2期新人玩转百度经验1379次分享第1期Win8.1实用小技巧2635次分享第1期小白装大神1876次分享◆请扫描分享到朋友圈C++类的成员函数调用全局变量不一致的问题
[问题点数:20分]
C++类的成员函数调用全局变量不一致的问题
[问题点数:20分]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2013年6月 Linux/Unix社区大版内专家分月排行榜第二2013年5月 Linux/Unix社区大版内专家分月排行榜第二2013年3月 Linux/Unix社区大版内专家分月排行榜第二2013年1月 Linux/Unix社区大版内专家分月排行榜第二2012年12月 Linux/Unix社区大版内专家分月排行榜第二2012年8月 Linux/Unix社区大版内专家分月排行榜第二2011年12月 Linux/Unix社区大版内专家分月排行榜第二2011年10月 C/C++大版内专家分月排行榜第二2011年10月 Linux/Unix社区大版内专家分月排行榜第二
2012年6月 C/C++大版内专家分月排行榜第三2012年6月 PHP大版内专家分月排行榜第三2012年5月 C/C++大版内专家分月排行榜第三2012年3月 Linux/Unix社区大版内专家分月排行榜第三2012年2月 Linux/Unix社区大版内专家分月排行榜第三2011年11月 C/C++大版内专家分月排行榜第三
匿名用户不能发表回复!|1. static 变量静态变量的类型 说明符是static。 静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量。 例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。2. 静态局部变量静态局部变量属于静态存储方式,它具有以下特点:(1)静态局部变量在函数内定义 它的生存期为整个源程序,但是其作用域仍与自动变量相同,只能在定义该变量的函数内使用该变量。退出该函数后, 尽管该变量还继续存在,但不能使用它。(2)允许对构造类静态局部量赋初值 例如数组,若未赋以初值,则由系统自动赋以0值。(3)对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。 根据静态局部变量的特点, 可以 看出它是一种生存期为整个源程序的量。虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用, 而且保存了前次被调用后留下的 值。 因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用全局变量也可以达到上述目的,但全局变量有时会造成 意外的副作用,因此仍以采用局部静态变量为宜。3.静态全局变量全局变量(外部变量)的说明之前再冠以static 就构 成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局 变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在 定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此 可以避免在其它源文件中引起错误。从以上分析可以看出,&把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量 后是改变了它的作用域, 限制了它的使用范围。因此static 这个说明符在不同的地方所起的作用是不同的。4. static 函数…..内部函数和外部函数当一个源程序由多个源文件组成时,C语言根据函数能否被其它源文件中的函数调用,将函数分为内部函数和外部函数。1 内部函数(又称静态函数)如果在一个源文件中定义的函数,只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用,这种函数称为内部函数。定义一个内部函数,只需在函数类型前再加一个“static”关键字即可,如下所示:static 函数类型 函数名(函数参数表){……}关键字“static”,译成中文就是“静态的”,所以内部函数又称静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件。使用内部函数的好处是:&不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名,因为同名也没有关系。2 外部函数外部函数的定义:在定义函数时,如果没有加关键字“static”,或冠以关键字“extern”,表示此函数是外部函数:[extern] 函数类型 函数名(函数参数表){……}调用外部函数时,需要对其进行说明:[extern] 函数类型 函数名(参数类型表)[,函数名2(参数类型表2)……];[案例]外部函数应用。(1)文件mainf.cmain(){ extern void input(…),process(…),output(…);input(…); process(…); output(…);}(2)文件subf1.c……extern void input(……){……}(3)文件subf2.c……extern void process(……){……}(4)文件subf3.c……extern void output(……){……}1、static 声明的变量在C语言中有两方面的特征:
1)、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。
2)、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。
2、问题:Static的理解  关于static变量,请选择下面所有说法正确的内容:  A、若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;  B、若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;  C、设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题;  D、静态全局变量过大,可那会导致堆栈溢出。  答案与分析:  对于A,B:根据本篇概述部分的说明b),我们知道,A,B都是正确的。  对于C:根据本篇概述部分的说明a),我们知道,C是正确的(所谓的函数重入问题,下面会详细阐述)。  对于D:静态变量放在程序的全局数据区,而不是在堆栈中分配,所以不可能导致堆栈溢出,D是错误的。  因此,答案是A、B、C。3、问题:不可重入函数  曾经设计过如下一个函数,在代码检视的时候被提醒有bug,因为这个函数是不可重入的,为什么?
unsigned int sum_int( unsigned int base ){  static unsigned int sum = 0; // 注意,是static类型的。 for (index = 1; index &= index++) {  sum += } }
  答案与分析:  所谓的函数是可重入的(也可以说是可预测的),即:只要输入数据相同就应产生相同的输出。  这个函数之所以是不可预测的,就是因为函数中使用了static变量,因为static变量的特征,这样的函数被称为:带“内部存储器”功能的的函数。因此如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量,这种函数中的static变量,使用原则是,能不用尽量不用。  将上面的函数修改为可重入的函数很简单,只要将声明sum变量中的static关键字去掉,变量sum即变为一个auto 类型的变量,函数即变为一个可重入的函数。
  当然,有些时候,在函数中是必须要使用static变量的,比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。
阅读(...) 评论()基于C++全局变量的声明与定义的详解
转载 & & 作者:
本篇文章是对C++全局变量的声明与定义进行了详细的分析介绍,需要的朋友参考下
(1)编译单元(模块)在VC或VS上编写完代码,点击编译按钮准备生成exe文件时,编译器做了两步工作:第一步,将每个.cpp(.c)和相应的.h文件编译成obj文件;第二步,将工程中所有的obj文件进行LINK,生成最终.exe文件。那么,错误可能在两个地方产生:一个,编译时的错误,这个主要是语法错误;一个,链接时的错误,主要是重复定义变量等。编译单元指在编译阶段生成的每个obj文件。一个obj文件就是一个编译单元。一个.cpp(.c)和它相应的.h文件共同组成了一个编译单元。一个工程由很多编译单元组成,每个obj文件里包含了变量存储的相对地址等。(2)声明与定义函数或变量在声明时,并没有给它实际的物理内存空间,它有时候可保证你的程序编译通过;函数或变量在定义时,它就在内存中有了实际的物理空间。如果你在编译单元中引用的外部变量没有在整个工程中任何一个地方定义的话,那么即使它在编译时可以通过,在连接时也会报错,因为程序在内存中找不到这个变量。函数或变量可以声明多次,但定义只能有一次。(3) extern作用作用一:当它与"C"一起连用时,如extern "C" void fun(int a, int b);,则编译器在编译fun这个函数名时按C的规则去翻译相应的函数名而不是C++的。作用二:当它不与"C"在一起修饰变量或函数时,如在头文件中,extern int g_nN,它的作用就是声明函数或变量的作用范围的关键字,其声明的函数和变量可以在本编译单元或其他编译单元中使用。即B编译单元要引用A编译单元中定义的全局变量或函数时,B编译单元只要包含A编译单元的头文件即可,在编译阶段,B编译单元虽然找不到该函数或变量,但它不会报错,它会在链接时从A编译单元生成的目标代码中找到此函数。(4)全局变量(extern)有两个类都需要使用共同的变量,我们将这些变量定义为全局变量。比如,res.h和res.cpp分别来声明和定义全局变量,类ProducerThread和ConsumerThread来使用全局变量。(以下是QT工程代码) 代码如下:/**********res.h声明全局变量************/& #pragma once& #include &QSemaphore&& const int g_nDataSize = 1000; // 生产者生产的总数据量& const int g_nBufferSize = 500; // 环形缓冲区的大小& extern char g_szBuffer[]; // 环形缓冲区& extern QSemaphore g_qsemFreeB // 控制环形缓冲区的空闲区(指生产者还没填充数据的区域,或者消费者已经读取过的区域)& extern QSemaphore g_qsemUsedB // 控制环形缓冲区中的使用区(指生产者已填充数据,但消费者没有读取的区域)& /**************************/& 上述代码中g_nDataSize、g_nBufferSize为全局常量,其他为全局变量。 代码如下:/**********res.cpp定义全局变量************/& #pragma once& #include "res.h"& // 定义全局变量& char g_szBuffer[g_nBufferSize];& QSemaphore g_qsemFreeBytes(g_nBufferSize);& QSemaphore g_qsemUsedB& /**************************/& 在其他编译单元中使用全局变量时只要包含其所在头文件即可。 代码如下:/**********类ConsumerThread使用全局变量************/& #include "consumerthread.h"& #include "res.h"& #include &QDebug&& ConsumerThread::ConsumerThread(QObject* parent)& : QThread(parent) {& }& ConsumerThread::ConsumerThread() {& }& ConsumerThread::~ConsumerThread() {& }& void ConsumerThread::run() {& &for (int i = 0; i & g_nDataS i++) {& & g_qsemUsedBytes.acquire();& qDebug()&&"Consumer "&&g_szBuffer[i % g_nBufferSize];& & g_szBuffer[i % g_nBufferSize] = ' ';& & g_qsemFreeBytes.release();& &}& &qDebug()&&"&&Consumer Over";& }& /**************************/& 也可以把全局变量的声明和定义放在一起,这样可以防止忘记了定义,如上面的extern char g_szBuffer[g_nBufferSize]; 然后把引用它的文件中的#include "res.h"换成extern char g_szBuffer[];。但是这样做很不好,因为你无法使用#include "res.h"(使用它,若达到两次及以上,就出现重定义错误;注:即使在res.h中加#pragma once,或#ifndef也会出现重复定义,因为每个编译单元是单独的,都会对它各自进行定义),那么res.h声明的其他函数或变量,你也就无法使用了,除非也都用extern修饰,这样太麻烦,所以还是推荐使用.h中声明,.cpp中定义的做法。(5)静态全局变量(static)注意使用static修饰变量,就不能使用extern来修饰,即static和extern不可同时出现。static修饰的全局变量的声明与定义同时进行,即当你在头文件中使用static声明了全局变量,同时它也被定义了。static修饰的全局变量的作用域只能是本身的编译单元。在其他编译单元使用它时,只是简单的把其值复制给了其他编译单元,其他编译单元会另外开个内存保存它,在其他编译单元对它的修改并不影响本身在定义时的值。即在其他编译单元A使用它时,它所在的物理地址,和其他编译单元B使用它时,它所在的物理地址不一样,A和B对它所做的修改都不能传递给对方。多个地方引用静态全局变量所在的头文件,不会出现重定义错误,因为在每个编译单元都对它开辟了额外的空间进行存储。以下是Windows控制台应用程序代码示例: 代码如下:/***********res.h**********/& static char g_szBuffer[6] = "12345";& void fun();& /************************/&
代码如下:/***********res.cpp**********/& #include "res.h"& #include &iostream&& & void fun() {& &for (int i = 0; i & 6; i++) {& & g_szBuffer[i] = 'A' +& &}& &cout&&g_szBuffer&&& }& /************************/&
代码如下:/***********test1.h**********/& void fun1();& /************************/&
代码如下:/***********test1.cpp**********/& #include "test1.h"& #include "res.h"& #include &iostream&& & void fun1() {& fun();& &for (int i = 0; i & 6; i++) {& & g_szBuffer[i] = 'a' +& &}& &cout&&g_szBuffer&&& }& /************************/&
代码如下:/***********test2.h**********/& void fun2();& /************************/&
代码如下:/***********test2.cpp**********/& #include "test2.h"& #include "res.h"& #include &iostream&& & void fun2() {& &cout&&g_szBuffer&&& }& /************************/&
代码如下:/***********main.cpp**********/& #include "test1.h"& #include "test2.h"& int main() {& &fun1();& &fun2();& &system("PAUSE");& &return 0;& }& /************************/& 运行结果如下:按我们的直观印象,认为fun1()和fun2()输出的结果都为abcdef,可实际上fun2()输出的确是初始值。然后我们再跟踪调试,发现res、test1、test2中g_szBuffer的地址都不一样,分别为0xxx,这就解释了为什么不一样。注:一般定义static 全局变量时,都把它放在.cpp文件中而不是.h文件中,这样就不会给其他编译单元造成不必要的信息污染。(6)全局常量(const)const单独使用时,其特性与static一样(每个编译单元中地址都不一样,不过因为是常量,也不能修改,所以就没有多大关系)。const与extern一起使用时,其特性与extern一样。[code]extern const char g_szBuffer[];&&&&& //写入 .h中& const char g_szBuffer[] = "123456"; // 写入.cpp中& [/code
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具静态成员变量能作为其他类的成员函数的参数吗_百度知道
静态成员变量能作为其他类的成员函数的参数吗
我有更好的答案
public class Test {
public static int a=1;//静态成员变量}//运行结果正常输出1,在java中静态成员变量能作为其他类的成员函数的参数public class TestStatic {
public void test(int a){//测试方法test
System.out.println(a);//相当于C++的cout&&a;
public static void main(String[] args){
TestStatic testStatic = new TestStatic();
testStatic.test(Test.a);//静态成员传入test()方法。
}}LZ还是亲自测试一下就知道结果了。
采纳率:75%
肯定可以撒,静态成员变量和非静态成员变量都可以,传过去的是这个变量的值,而不是变量本身
可以的!java,c++都可以!设置为静态代表类的成员。而不是对象的!
能!只要你定义的是全局变量,或者在其他你需要用那个类里面包含你定义这个静态成员变量的类的头文件。
其他7条回答
为您推荐:
其他类似问题
静态成员变量的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。

我要回帖

更多关于 shell 函数 全局变量 的文章

 

随机推荐