C++中static关键字的用法

static变量与全局变量有很多相似之处,下面是他们主要的异同点:

相同:1)都存储在静态存储区,相比之下局部变量是存储在程序栈中的。

            2)生命周期与程序的生命周期相同,从初始化直到程序运行结束一直存在。而局部变量的使用周期只在它的定义域中(即所在的{}内)。

不同:全局变量的作用域就是全局,而静态成员的作用域有“局部性”,即稳健的作用域。

稳健的作用域是最难理解的地方,其实就是static变量同时具有全局变量和局部变量的性质。与全局变量相同的地方是生命周期,而与局部变量相同的是作用域。在一个函数内部定义的static变量在第一次定义的时候即存在,不会因为函数调用完毕而被销毁,下次调用该函数时该static变量已经存在,会跳过定义static变量的语句。static全局变量只能作用于定义它的文件里,不能作用到其他文件里。一般的全局变量可以使用extern关键字进行引用。

在类中定义的static成员变量和成员函数也具有一些独特的性质,在下面的程序里展现。

<pre name="code" class="cpp">/**
    这个工程主要实现一些static的使用方法
*/
#include <iostream>

using namespace std;

/**在第一次调用fun函数时,value被定义,应为static对象只能被定义一次,
   所以之后使用该函数时,会“跳过”定义static对象的语句!*/
void fun1(int i)
{
    static int value = i; //该语句只在fun1第一次被调用时执行
    cout << value << endl;
}

void fun2(int i)
{
    static int value; //该语句只在fun1第一次被调用时执行
    value = i; //赋值语句正常进行
    cout << value << endl;
}

static int global_a = 0;
static void fun3()
{
    cout << "static function" << endl;
}

/**sv只在第一次调用时被定义,之后调用改函数将掉过调用语句,
   cv在每次调用时都被重新定义。*/
void fun4(int i)
{
    static int sv = i;
    const int cv = i;
    cout << sv << " " << cv << endl;
}

class A
{
public:
    static int pub;
    static A a; //正确,可以在类内定义该类的static的实例
    //A b; 错误,类A的定义不完整
    A *pa; //正确,指针的大小是确定的
    static void fun1() //正确,静态成员函数可以定义在类内,也可以定义在类外。在类外定义不能加static。
    {
        //++i; 错误,不能是用非静态成员!
        ++j;
        cout << j << endl;
        //cout << a.i << endl;
        //cout << a.j << endl;
    }
    void fun2()
    {
        ++i;
        ++j;
        cout << i << " " << j << endl;
        //cout << a.i << " " << a.j << endl;
    }
private:
    int i = 0;
    //static int j = 0; 错误,不能在类的内部定义静态成员!
    static int j; //在类内只能声明静态成员!
};
//在类外对静态成员进行定义,其目的是防止类的多个实例对static的重复定义!
int A::pub = 0;
int A::j = 0;

int main()
{
    /**1: static 在一般函数中的使用方法。
          注意static对象只能“定义”一次!*/
    for(int i=0; i<5; ++i)
        fun1(i); //输出5个0
    for(int i=0; i<5; ++i)
        fun2(i); //输出1 2 3 4 5
    for(int i=0; i<5; ++i)
        fun4(i);

    /**2: static对象的定义与初始化问题,static对象在定义时可以不初始化,
          这点与const对象不同,const对象必须在定义时初始化!*/
    static int i;
    i = 0;

    /**3: static作为全局变量,与普通全局变量的区别是static全局变量只能初始化一次,
          表示其他文件的不能引用这个static变量,该成员只对当前文件有效!
          static函数是同样的道理!*/
    cout << global_a << endl;

    /**4: 类中的静态成员和静态成员函数(重点)。*/
    cout << A::pub << endl;  //正确,可以直接用类名调用类的public的static的成员变量。
    cout << A::a.pub << endl;
    A a, b;
    a.fun1(); //输出1
    b.fun1(); //输出2,具有一般静态成员的“记忆”功能
    A::a.fun1();  //正确
    //A::a.fun2(); //错误

    return 0;
}
 
 

总之,理解static就是要理解它所定义的变量或函数的生命周期和作用范围(全局+局部)!

update: 2015-03-25,最近了解了一个static的新用法,就是在类内可以定义该类的static实例,而定义一般的该类的实例是不可以的!有什么作用呢?就是在主函数中可以不使用该类的实例来调用该类的static的成员函数,和使用static&public的成员变量。

update: 2015-03-31,这里对“该类的static实例”的理解有问题!在最新的博客“类内的static实例”进行了新的说明!



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值