这里分成两个方面来讲:
1.对于C语言
原则一:只用进行一次初始化
但是有一个原则必须讲,static所存储的位置:
还是把一个进程进行的位置放出:
.text:指的是代码段
.data和.bss是我们要重点讨论的段:
这两个段存储着我们全局变量(包括全局静态变量和全局变量)
.data:保存着我们已经初始化的全局变量和全局静态变量
.bss(block of start symbol)(虽然我更喜欢叫它best save space):保存着我们未初始化的全局变量和全局静态变量。
从这点可以明白我们的静态变量不在堆中,所以只用进行一次初始化就可以存在空间中,类似于全局变量。
其他段简单说明一下:
.symtab:符号段。
.debug .line这两个段在我们调试的过程中才会出现,或许我们在加入-g的时候才会出现这两个段。
原则二:对于多文件引用的过程中,只能本文件使用该变量或者函数
这也是static关键词区别于全局变量的地方,我们利用static来保护所在文件的static 变量以及static 函数不被文件访问。
具体的代码暂时不写啦,这个好写。
2.对于C++而言:
对于C++而言,我们无非要考虑的都是static放在对象里面的情况。
也就是static成员变量和static成员函数的区别:
(1). static 成员变量
根据我们的原则一,static存在于.data段中,被这个类的所有对象使用,所有对象共用同一个类的static成员变量,并在类外进行初始化。(常见的例子就是:银行的总收益情况,所有对象加的收益都得加在一起),这里有个例子可以说明:
#include<iostream>
using namespace std;
class Point2d{
public:
virtual void Foo(){}
virtual void Boo(){}
virtual void non_overwrite(){}
protected:
float _x, _y;
};
class Vertex: public Point2d{
public:
virtual void Foo(){}
virtual void BooVer(){}
protected:
Vertex *next;
};
class Point3d: public Point2d{
public:
virtual void Boo3d(){}
protected:
float _z;
};
class Vertex3d: public Vertex, public Point3d{
public:
void test(){}
static void test3(){}
static int a;
protected:
float mumble;
};
int Vertex3d::a=1;
int main()
{
Vertex3d vertex;
vertex.test();
cout<<"the size of Vertex3d: "<<sizeof(Vertex3d)<<endl;
return 0;
}
不过值得注意的是,加了staitc变量对这个sizeof(Vertex3d)不会造成大小的变量:
但是,把this指针打印出来,还是会特定看到static变量,如下图所示:
大小不会发生改变。
(2) 静态成员函数
静态成员函数可就厉害了,这里要说明几个特性:
1.我们在调用对象的成员函数的时候,编译器会传入一个this指针,通过这个this指针我们可以访问对象的静态和非静态变量。
2。但是我们我们的静态成员函数不会传入this指针,这就导致了我们不能访问对象的非静态变量以及其他对象的变量,只用访问自己的非静态变量。
Reference:
1.分析类的成员变量的各种测试
https://www.cnblogs.com/codingmengmeng/p/5906282.html
2.分析static在C/C++的用法:
https://www.cnblogs.com/songdanzju/p/7422380.html