独一无二----静态成员变量

原创 2001年09月10日 16:47:00

独一无二

                                          ----静态成员变量

作者:HolyFire

我们学习C++的时候知道静态变量的特性,他不是临时变量,在编译期间就已经产成。用一个例子就能说明问题。

#include <iostream>

using namespace std;

class A{

public:

        A(){ cout << "Can you see me Now!" << endl; }

        ~A(){ cout << "I'm Go Away!" << endl; }

};

void TestStatic( void )

{

        static A a;

}

void main()

{

        cout << "Program Start!" << endl;

        TestStatic();

        TestStatic();

        TestStatic();

        cout << "Program End!" << endl;

}

结果是:

Program Start!

Can you see me Now!

Program End!

I'm Go Away!

A a只被定义了一次,而且析构是在主程序退出以后才进行的。这说明了什么呢,A avoid TestStatic( void )是同一个实例,他存在于整个程序但是只有在void TestStatic( void )中能访问他。

不相信?那我们来试试看。

#include <iostream>

using namespace std;

class A{

private:

        int count;

public:

        A():count(0){ cout << "Can you see me Now!" << endl; }

        ~A(){ cout << "I'm Go Away!" << endl; }

        void Inc(){ count++; }

        int Count(){ return count; }

};

void TestStatic( void )

{

        static A a;

        a.Inc();

        cout << "count's value is : " << a.Count() << endl;

}

void main()

{

        cout << "Program Start!" << endl;

        TestStatic();

        TestStatic();

        TestStatic();

        cout << "Program End!" << endl;

}

结果是:

Program Start!

Can you see me Now!

count's value is : 1   //初始化count0Inc导致count自加值应该为1

count's value is : 2   //没有初始化,Inc导致count自加值应该为2

count's value is : 3   //没有初始化,Inc导致count自加值应该为3

Program End!

I'm Go Away!

事实说明了一切,那么他是如何实现的呢,C++编译器里,他被创建在一个内存区域里,这块区域不是堆也不是栈,编译器在编译阶段就将他们记住,并为他们做好分配工作,如此一来就可以实现这个特性。

看起来他的作用有些象全局变量,但是我们知道,使用全局变量会整加模块的耦合性,降低代码的通用性,所以静态成员变量的出现为我们编程带来的灵活性。

如何将这个小东西用在我们的面向对象编程中呢。他扮演一个什么样的角色呢,这正是我要说的。

我们知道,类的成员变量表示了一个类的属性,对应着对象的物质特性,他们在类的某个实例创建的时候创建,消亡的时候消亡。但是上面说到,静态变量在编译期间就已经存在了,也就是并不随着实例创建的时候创建,消亡的时候消亡。是这样吗。看事实说话。

#include <iostream>

using namespace std;

class A{

public:

        A() { cout << "A is On!" << endl; }

        ~A() { cout << "A is OFF!" << endl; }

};

class B{

public:

        B() { cout << "B is On!" << endl; }

        ~B() { cout << "B is OFF!" << endl; }

private:

        static A a;

};

A B::a;

void main()

{

        cout << "Program Start!" << endl;

        B b1,b2,b3;

        cout << "Program End!" << endl;

}

结果是:

A is On!  //瞧我又说中了,主程序还没有运行,构造函数就开始工作了,这时B的实例还没有登场

Program Start!

B is On!  //b1创建了,但是b1.a并没有创建

B is On!

B is On!

Program End!

B is OFF!  //B的实例销毁了,但是成员变量a没有销毁

B is OFF!

B is OFF!

A is OFF!  //看吧,这才是A的析构函数

注意一个约定:

A B::a;

静态成员变量的初始化一定要在主函数外面,而且静态成员变量一定要初始化。

事实上B::a并不属于B,将他作为B的成员只是为了确定访问的权限

private:

        static A a;

因为这样设定以后只有B才能访问B::a,当然设计的时候要考虑清楚,如果aB并没有关系,那么这样的设计就没有什么实际的意义。

那么如何设计才能运用这个特性呢。

我们来举个例子。

我们有时候想知道类的实例有几个,也就是被实例化了几次。比如

class A;

A a1,a2,a3;

那么就应该被实例化了3次。能知道这个信息应该很不错。如果用一个全局变量,那么要考虑的问题很多,全局变量会被人任意修改,全局变量定义在那里以及全局变量初始化在那里也会带来困惑,全局变量会不会跟别的全局变量重名等等。

既然静态变量可以实现一些全局变量的功能,何不牛刀小试,看看效果如何。首先静态成员变量只有一个,而且不是类的真实属性,实际上只有一个变量,不会增加类的负担;第二可以给他加上访问限制,只要不是public那么就不能随意修改。既然好处多多,那么就开工。

#include <iostream>

using namespace std;

class A{

public:

       A(){ count++; };  //当产生一个实例的时候计数器加一

    ~A(){ count--; }  //当销毁一个实例的时候计数器减一

       int GetInstanceCount(){ return count; }

private:

       static int count;

};

int A::count = 0;

void main()

{

       cout << "Program Start! " << endl << endl;

       A a1,a2,a3;

       {

              A a4,a5,*pa;

              cout << "Now, Have a1 ,a2 ,a3 , a4 ,a5 Instances!" << endl;

              cout << "Number of class A's Instance is : " << a1.GetInstanceCount() << endl << endl;

              pa = new A;

              cout << "Now Creat a class A's Instance!" << endl;

              cout << "Number of class A's Instance is : " << a2.GetInstanceCount() << endl << endl;

              delete pa;

       }

       cout << "While class's Instances a4 , a5 , pa destroy!" << endl;

       cout << "Only a1 , a2 , a3 Left , is the Count of Instance is 3 ?" << endl;

       cout << "Number of class A's Instance is : " << a3.GetInstanceCount() << endl << endl ;

}

结果是:

Program Start!

Now, Have a1 ,a2 ,a3 , a4 ,a5 Instances!  //a1 ,a2 ,a3 ,a4 ,a5五个实例

Number of class A's Instance is : 5       //没错,正是五个

Now Creat a class A's Instance!        //在堆里创建了一个,使用pa得到他的引用

Number of class A's Instance is : 6      //跟想的一样,数目增加了

While class's Instances a4 , a5 , pa destroy!  //在堆里释放一个,栈里释放2

Only a1 , a2 , a3 Left , is the Count of Instance is 3 ? //6 – 1 –2 当然等于3

Number of class A's Instance is : 3  我说的没错吧。

因为在构造函数里操作的是同一个变量,所以才能得到正确的结果。这个技术在很多方面得到应用,比如,互斥信号,象动态连接库一样的引用计数器等等。

这里要记住的是,类的静态成员变量实际上只有一个,它不随着类的实例的创建/销毁而增加/减少。它不是类的真正成员,并不是类的一部分。

2001/9/7

丁宁 

C++静态成员变量和静态成员函数使用总结

C++静态成员变量和静态成员函数使用总结: 一.静态成员变量:          类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员。和其他数据成员一样,静态数据成员...
  • fanyun_01
  • fanyun_01
  • 2016年05月16日 09:11
  • 7434

再探私有/公有静态成员变量与私有静态成员方法

问题1: 为什么在类内的静态成员定义后,要到类的外部在定义和初始化? 问题2:为什么类的静态成员在类外部的定义只能一次? 问题3:私有的静态成员变量如何初始化,访问权限还是私有么? 问题4:在程序执行...
  • tianjian789
  • tianjian789
  • 2015年09月06日 12:20
  • 1981

PHP 类的静态成员变量和普通成员变量对比

有很多人可能弄不清楚,在PHP中类的静态成员变量和普通成员变量有什么区别? 1、类的静态方法只能访问静态成员变量,而不能访问非静态成员变量 2、静态成员变量不需要实例化就能访问,且访问速度快一些 ...
  • lhbeggar
  • lhbeggar
  • 2015年05月28日 11:04
  • 2921

静态方法 实例成员变量 静态成员变量 局部变量

实例方法必须在类实例化后通过对象来调用,而静态方法可以在类实例化之前就使用。与成员变量不同的是,无论哪种方法,在内存中只有一份。 在外部调用静态方法时,可以使用类名.方法名的方式,也可以使用对象名.方...
  • vincentLCY
  • vincentLCY
  • 2015年09月04日 17:42
  • 1122

由类模版中static成员变量的定义引发的思考。。。

说到这个问题还要从一个项目说起,项目中整个系统的日志部分是通过单例模式进行管理的,在设计单例模式的时候,单例类的定义是定义成模版类,且为了实现每个单例类只能有一个实例,实例化返回的对象设计成静态成员变...
  • anonymalias
  • anonymalias
  • 2013年02月25日 22:27
  • 2121

Java基础——成员变量、局部变量和静态变量的区别

之前在刚开始学习Java的时候,就谈了谈Java基础中的变量,虽然知道这货以后会经常用到,但没想到了基本语法这里,竟然有冒出来了成员变量、局部变量和静态变量。变来变去太容易让人搞晕了,挑拣出来梳理一下...
  • haovip123
  • haovip123
  • 2015年02月19日 18:30
  • 13078

Java中静态变量,成员变量,局部变量,常量

在java中,类是最基本的单位,就是定义类中的成员(成员变量和成员方法等。) 静态变量也叫类变量,是类中独立于方法之外的变量,用static 修饰。 static表示“静态的”,“全局的”,也可以...
  • chaplinlong
  • chaplinlong
  • 2016年04月04日 09:37
  • 1662

静态成员函数不可以访问类中的成员变量

原因:因为静态成员函数在类对象构造时没有分配this指针(非静态成员函数则具有this指针),相当于是全局函数,是属于类的,而类的成员变量只有类对象(实例)能够访问,成员变量只有实例化才有意义。 解...
  • Kelvin_Yan
  • Kelvin_Yan
  • 2016年11月15日 15:51
  • 1896

c++中静态成员变量的两个特殊属性

static成员变量是在初始化(而不是在类声明时候)才定义出来的,如果没有对静态成员变量进行初始化,yyn...
  • guoliushui
  • guoliushui
  • 2014年07月07日 00:57
  • 1569

MFC C++类中的静态成员变量和静态成员函数的作用

数据成员可以分静态变量、非静态变量两种.  静态成员:静态类中的成员加入static修饰符,即是静态成员.可以直接使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员需要实例化才会分...
  • skdkjxy
  • skdkjxy
  • 2013年12月02日 14:39
  • 1234
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:独一无二----静态成员变量
举报原因:
原因补充:

(最多只允许输入30个字)