static在修饰不同的类型的时候有着不同的含义,一般我们可以用关键修饰:
- 变量 【静态变量】
- 函数中的变量 / 局部静态变量
- 类的静态数据成员
- 类的成员 【静态成员】
- 静态对象
- 类的静态成员函数
静态变量
1.函数中的静态变量:当一个函数中变量被修饰成静态的时候,它的生存期为整个函数的生存期。即使这个函数被调用了很多次,但是对改变量的内存分配只是一次,其值会保持上一次调用时候的值
//函数中的静态变量
#include <iostream>
#include <string>
using namespace std;
void demo()
{
// static variable
static int count = 0;
cout << count << " ";
// value is updated and will be carried to next functions calls
count++;
}
int main()
{
for (int i = 0; i < 5; i++)
demo();
return 0;
}
输出
0 1 2 3 4
局部作用域的静态变量的特点是:
- 不会随着函数的每次调用产生一个副本
- 也不会随着函数的返回而失效
2.类中的静态变量:当类中的某个成员变量被定义为静态的时候,它只被初始化一次,被类的对象所共享。不会因为多个对象而有多个副本,因此不能用构造函数去初始化
#include <iostream>
using namespace std;
class GfG
{
public :
static int i;
GfG()
{
// do noting
}
};
int main()
{
GfG obj1;
GfG obj2;
obj1.i = 2;
obj2.i = 3;
cout << obj1.i << obj2.i;
}
上述的程序试图给静态变量创造几个副本给不同的对象使用,但这样是不允许的。所以 类中的静态成员仅仅在类的定义中进行引用性声明,然后必须在命名空间作用域的某个地方使用类名限定定义性声明
#include<iostream>
using namespace std;
class GfG
{
public:
static int i;
GfG()
{
// Do nothing
};
};
// 类之外再加以定义
//用这种专门的形式为它们分配空间。
//非静态数据成员无须以此方式来定义,因为他们的空间是与他们所属对象的空间同时分配的
int GfG::i = 1;
int main()
{
GfG obj;
// prints value of i
cout << obj.i;
}
- 类的静态数据成员,在每个类中只有一个副本,由该类的所有对象共同维护和使用,从而实现了同一类的不同对象的之间的数据共享。
类的静态 【Static Members of Class】(暂且这样翻译)
1. 静态对象
首先比较下同一个类的 非静态对象和静态对象 例子
// CPP program to illustrate
// when not using static keyword
#include<iostream>
using namespace std;
class GfG
{
int i;
public:
GfG()
{
i = 0;
cout << "Inside Constructor\n";
}
~GfG()
{
cout << "Inside Destructor\n";
}
};
int main()
{
int x = 0;
if (x==0)
{
GfG obj;
}
cout << "End of main\n";
}

输出
// CPP program to illustrate
// class objects as static
#include<iostream>
using namespace std;
class GfG
{
int i = 0;
public:
GfG()
{
i = 0;
cout << "Inside Constructor\n";
}
~GfG()
{
cout << "Inside Destructor\n";
}
};
int main()
{
int x = 0;
if (x==0)
{
static GfG obj;
}
cout << "End of main\n";
}

输出
两者的区别在于析构函数什么时候被调用,静态对象拥有了和程序相同的生存期。
2.类的静态函数成员
- 普通成员函数 : 调用必须通过对象名
- 静态成员函数 :
- 调用可以通过 类名 或者 对象名 【推荐类名,即使通过对象名,起作用的也只是对象的类型信息,与所使用的具体信息没有关系】
- 静态成员函数 可以直接访问 该类的静态数据 和 函数成员,而访问非静态成员,必须通过对象名
include <iostream>
using namespace std;
class GfG
{
public :
static void printMsg()
{
cout << '' Welcome to GfG!'';
}
};
int main()
{
GfG::printMsg();
// 直接通过类名来访问
}

总结
- static 修饰
- 普通变量 如函数中的变量 局部静态变量
- 对象 静态对象
- 类的数据成员 / 函数成员
问题 static 的作用
static全局变量 和 普通全局变量
- 改变了作用域 (限制了其作用域)
static 局部变量 和 普通局部变量 - 改变了生存期
static 函数 和 普通函数 -
static函数在内存中只有一份,普通在每个调用中维持一个拷贝
