关键字static

关键字static

最近的面试都有涉及到,所以来深入汇总一下它的特点

  1. 三大特性
  2. 生命周期
  3. 作用范围
  4. 类中的特点

1. 三大特性

1.1 隐藏

const关键字也和static一样,有隐藏的作用。仅作用于本文件,避免同名的冲突。

当同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。

1.2 初始化为0

其实全局变量也具备这一属性,因为全局变量也存储在静态数据区。在静态数据区,内存中所有的字节默认值都是0x00,某些时候这一特点可以减少程序员的工作量。

1.3 持久化

(static变量中的记忆功能和全局生存期)存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。共有两种变量存储在静态存储区:全局变量和static变量,只不过和全局变量比起来,static可以控制变量的可见范围,说到底static还是用来隐藏的。

2. 生命周期

  • 非静态局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束
  • 全局变量静态变量的生命周期是:整个程序的生命周期
生命周期 无static 有static
局部变量 进入作用域生命周期开始,出作用域生命周期结束 整个程序的生命周期
全局变量 整个程序的生命周期 整个程序的生命周期
类中成员变量 每个对象都有一份拷贝 属于整个类所有,所有对象只有一份拷贝

3. 作用范围

  • 静态与非静态局部变量限制在局部范围内,
  • 非静态全局变量作用于整个工程,静态全局变量作用于当前文件;
  • 非静态函数,可在其他文件中引用;静态函数只能在当前文件中使用
作用范围 无static 有static
局部变量 局部范围 局部范围
全局变量 整个工程 当前文件
函数 可在其他文件中引用 仅在当前文件中使用
类成员变量 与对象绑定 可直接调用,不需要new一个对象
类成员函数 与对象绑定 可直接调用,不需要new一个对象

4. 类中的static其他特性

  1. static类成员变量必须要在类外进行初始化,static修饰的变量先于对象存在,所以static修饰的变量要在类外初始化;
  2. 由于static修饰的类成员函数属于类,不属于对象,因此static类成员函数是没有this指针的,this指针是指向本对象的指针。正因为没有this指针,所以static类成员函数不能访问非static的类成员,只能访问 static修饰的类成员;非static函数,既可以访问非static成员也可以访问static成员
  3. static类成员函数不能被virtual修饰,static成员不属于任何对象或实例,所以加上virtual没有任何实际意义;静态成员函数没有this指针,虚函数的实现是为每一个对象分配一个vptr指针,而vptr是通过this指针调用的,所以不能为virtual;虚函数的调用关系,this->vptr->ctable->virtual function

可以看一下static典型的使用例子,饿汉式的单例模式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Singleton{
static Singleton* getInstance(){ //static成员函数只能够访问static成员变量
return &s_instance;
}
private:
Singleton(){}
~Singleton(){}
Singleton(const Singleton &) = delete;
Singleton& operator=(const Singleton &) = delete;
private:
static Singleton s_instance;
};

Singleton Singleton::s_instance; //在程序入口之前就完成单例对象的初始化

关键字static
https://wuhlan3.github.io/2022/09/14/关键字static/
Author
Wuhlan3
Posted on
September 14, 2022
Licensed under