static 关键字详细总结

static 在c/c++的作用

1):修饰全局变量时,表明一个全局变量只对定义在同一文件中的函数可见。                         

2):修饰局部变量时,表明该变量的值不会因为函数终止而丢失。              

 3):修饰函数时,表明该函数只在同一文件中调用。

c++独有:

 4):修饰类的数据成员,表明对该类所有对象这个数据成员都只有一个实例。即该实例归 所有对象共有。

 5):用static修饰不访问非静态数据成员的类成员函数。这意味着一个静态成员函数只能访问它的参数、类的静态数据成员和全局变量

深入了解

我们需要理解两点关于static的知识:

1,由static修饰的变量存储在虚拟内存空间的数据区,而非静态成员变量一般存放在堆区或者栈区;(全局变量和常量也存放在数据区)

2.由static修饰的函数以及非静态函数都存在于存储在虚拟地址空间的代码区;

分别介绍:

静态全局变量的特点

静态全局变量不能被其他文件所用(全局变量就可以)

      声明static变量一般是为了在本cpp文件中的static变量不能被其他的cpp文件引用,但是对于头文件,因为cpp文件中包含了头文件,故相当于该static变量在本cpp文件中也可以被见到。当多个cpp文件包含该头文件中,这个static变量将在各个cpp文件中将是独立的,彼此修改不会对相互有影响。也就是可以理解为,当其他文件又定义了一个与其名字相同的变量,但是不会发生冲突,应为static隔离了文件
 

 静态局部变量的特点

1,,静态局部变量会在执行该变量首次声名时被初始化,且在全局数据区分配内存。

2,如果我们没有对静态局部变量对其进行初始化,会默认初始化为0;

 其中第一句static int c=1;为声明语句只会执行一次;在执行该次时被初始化,且不能够重复进行声明,否则者为重定义,编译器报错。

3,静态局部变量和静态全局变量的区别是静态局部变量的作用域不同,即不能在函数体外进行调用,但是它始终存在于数据区,只有在程序运行退出后才会释放空间。而局部变量的话函数结束时,立刻释放空间,然后函数栈帧销毁

普通静态函数

        其特点和静态全局变量类似,只能够由本文件调用,其他文件可以生成具有相同名字的函数,原因是static做了一层隔离

类静态成员变量

1.所有有该类实例化出的对象共享同一个静态成员变量;

2.类的静态成员变量存储在数据区,会在第一次被声明初始化,默认初始化为0;

3.类的静态成员变量必须要在类外进行初始化,且只能初始化一次,否则则为重定义

        特殊情况:静态成员常量可以在类内初始化 :static const int a=1;

4..类的静态成员变量在类外的访问权限与其访问限定符有关(与普通成员类似);

5.类的成员函数可以通过self::访问静态成员变量;

类的静态成员函数

1.静态成员函数之间支持相互访问,即静态成员函数支持访问 静态成员函数 或静态成员变量。

2.静态成员函数不能调用非静态成员函数。(编译时就会报错);

3.非静态成员函数可以任意的访问静态成员变量和静态成员函数。

4.静态成员函数没有t参数列表this指针,因此静态成员函数不能设置为const(要理解并不是由于没有this指针才不能访问成员变量,下面有解释)

5.调用静态成员函数时,可以通过实例对象的方式在通过"." 或"->"来访问。也可以通过类名作用域限定符。(一般采用作用域限定符,因为在计算机内部通过"."->"都会被转化为最后一种形式)

        深入剖析:我们可以在类外直接调public修饰的静态成员函数,静态成员函数被调用时,可能并不是由类对象进行调用的 ,如果直接在类外进行调用,类中的成员变量还没有被实例化,这也是静态成员函数没有this的原因。因此静态成员函数是不能调用非静态成员函数的。但是他可以调全局变量和静态全局变量,原因是因为这些是都是在数据区存放的,已经完成初始化了。

int aaa = 5;
static int bbb = 1;
class B {
public:
	B():b(1){
	}
	int b;
	static int x ;
	static void func();
	static void func2();

};
void B::func() {
	B::x++;
	aaa++;
	cout << "nihao" << B::x <<" " << aaa << endl;

}
void B::func2() {
	B::x++;
	bbb++;
	cout << "nihaoma" << B::x <<" "<< bbb << endl;
}
int B::x=6;
int main() {

	B ss;
	ss.func();
	ss.func2();

	 return 0;
	

}

要使用静态成员函数的情景,或者说为什么要使用静态成员函数?

考虑到一种情形

通过定义public成员函数来访问私有静态成员变量的确是一个解决方案,但存在一个缺点:每次访问私有静态成员变量时,都必须要实例化一个对象才行,这样会浪费空间,有的情况,实例化对象还会带来一些不必要的麻烦。

程序员曾经为为了避免该麻烦而想到的一种优化方式:

((A*)NULL)->get_n();


       看起来不错,这样不需要实例化对象出来就达到了目的。但其实这样做很不安全,如果我在 get_n 成员函数中不小心使用了非静态成员变量b , 因为非静态成员只有实例化了对象才会给分配内存,这就会导致正在运行的程序崩溃。但是编译器却不会给报错,留下了安全隐患。因此,后来C++引入了静态成员函数。
参考文章:https://blog.csdn.net/u013471277/article/details/82851407

                     https://blog.csdn.net/ypshowm/article/details/89030194  

猜你喜欢

转载自blog.csdn.net/m0_56910081/article/details/126825632