c++中static的用法

发布时间 2023-06-10 09:06:28作者: 韓さん

1、静态全局变量

全局变量的空间会在程序的生命周期内分配,在全局变量的前面加上static,变成静态全局变量。

#include <iostream>
#include <string.h>
using namespace std;

static int n = 5;

int main()
{
    n = 10;
    printf("%d\n", n);
    return 0;
}

静态全局变量在全局数据区分配内存,那它和全局变量有啥区别呢?
全局变量不但在本文件中可以被访问,在其他文件中同样可以访问。写代码时很容易在不同文件定义相同名字的全局变量,这就会引发冲突。
而静态全局变量只能在声明它的整个文件可见,限制了该变量的访问范围。
同样的,静态全局函数,在全局函数前加上static,表示只能在声明文件中被访问。

2、静态局部变量

局部变量也就是定义在函数内部的变量,函数局部变量存放在栈区,该变量的生命周期由所在 {} 决定,进入 {} 作用范围而分配内存空间,退出 {} 作用范围而释放内存空间。
在局部变量的前面加上static,变成静态局部变量,即使多次调用该函数,静态变量的空间也只分配一次。

#include <iostream>
#include <string.h>
using namespace std;

void fun()
{
    static int n = 5;
    printf("%d\n", n);
    n++;
}
int main()
{
    int i;
    for(i=0; i<5; i++)
    {
        fun();
    }
    return 0;
}

前一次调用的变量值通过下一次函数调用传递,可以存储之前的函数状态。

3、静态成员变量

我们知道,一个类可以定义多个对象,每个对象都会对类中的普通成员变量进行空间分配,这些变量只由它所在对象使用。
静态成员变量是该类的所有对象所共有的。对于普通成员变量,每个类对象都有自己的一份拷贝,而静态成员变量整个类就一份,静态成员变量只分配一次内存,类的所有对象都共享这个变量,不属于任何一个类,不需要对象就可以访问。
静态成员变量不属于特定的对象,不会占用对象的内存,必须在类的外面进行初始化。对象的内存中只包括普通成员变量,注意不包括任何成员函数。sizeof(类名) 不会计算静态成员变量和成员函数。
普通成员变量随这对象的产生而产生,静态成员变量随着类的产生而产生,所以静态成员变量不能由构造函数初始化,即使没有对象,也可以访问静态全局变量。

#include <iostream>
#include <string.h>
using namespace std;

class A 
{
    public:
        static int n; //声明静态成员变量
};
int A::n = 5; //定义并初始化静态成员变量
int main()
{
    printf("n:%d, sizeof(A):%d\n", A::n, sizeof(A));
    return 0;
}

4、静态成员函数
就像类中的静态成员变量一样,静态成员函数也不依赖于类的对象,不具体作用于某个对象。
普通成员函数参数自带一个this指针,this指针指向类的对象本身,因为普通成员函数总是属于类对象,当函数被调用时,系统会把当前对象的起始地址赋给 this 指针。
静态成员函数属于类本身,因此不具有this指针。它无法访问属于类对象的非静态成员变量和非静态成员函数,它只能访问其他静态成员变量和静态成员函数。
可以通过对象来调用,但还是建议使 类名::静态成员函数 调用静态成员函数。
静态成员函数和静态成员变量在类实例化之前就已经存在可以访问,而此时非静态成员还是不存在的,因此静态成员函数不能访问非静态成员变量。

#include <iostream>
#include <string.h>
using namespace std;

class A 
{
    private:
        static int n; //声明静态成员变量
    public:
        static void fun();
        int m;
};
int A::n = 5; //定义并初始化静态成员变量
//定义静态成员函数,不能加static
void A::fun()
{
    printf("n:%d\n", n);
    // printf("m:%d\n", m); //error
}
int main()
{
    A aa;
    aa.fun();
    A::fun(); 
    return 0;
}