前言
在C++中,static关键字有多种用法,它可以应用于变量、函数和类成员。接下来进行介绍。
一、静态变量
1.静态局部变量
当变量声明为static时,空间将在程序的生命周期内分配。即使多次调用该函数,静态变量的空间也只分配一次,前一次调用中的变量值通过下一次函数调用传递。这对于在C / C ++或需要存储先前函数状态的任何其他应用程序非常有用。
void test() {
static int a = 0;
a++;
cout << "the value of a is:" << a<<endl;
}
int main()
{
int value;
for (int i = 0; i < 5; i++)
{
test();
}
system("pause");
return EXIT_SUCCESS;
}
上面程序的输出结果为1,2,3,4,5,这表明这些变量在函数第一次被调用时被初始化,不会在每次函数调用时重新初始化。
2.静态全局变量
在全局范围(函数外部)使用static关键字声明的变量被称为静态全局变量。这些变量的作用域限制在声明它们的源文件内,在其他文件中无法访问。
//file1.cpp
#include<iostream>
static int StaticVar = 10;
//file2.cpp
#include<iostream>
int main()
{
cout<<StaticVar<<endl; //错误!
}
3.静态变量与全局变量区别
静态变量容易与全局变量进行比较,因为两者有些相似之处,但总归是不一样的,接下来,从三个方面说明两者的不同。
3.1 作用域
静态变量:局部静态变量在声明它的函数或块内有效,在函数内声明的静态变量在整个程序的生命周期内都存在,但只能在声明它的函数内访问。而全局静态变量在整个文件中可见,它的作用域仅限于当前文件。在其他文件中不能直接访问全局静态变量,因为它们的名称是在文件作用域内的。
全局变量:全局变量在整个程序中可见,它的作用域覆盖整个程序,可以在其他文件中通过声明extern来访问全局变量。
3.2 连接性
**静态变量:**静态变量具有内部链接性(Internal Linkage),这意味着它们只在当前文件中可见,不能被其他文件访问。即使在不同文件中使用相同名称声明全局静态变量,它们实际上是不同的变量。
全局变量:全局变量具有外部链接性(External Linkage),可以在其他文件中通过声明extern来访问,并且在整个程序中都共享同一份变量。
3.3 生命周期
静态变量:静态变量在程序启动时初始化,并一直存在到程序结束。局部静态变量的值在函数调用之间保持不变。
全局变量:全局变量在程序启动时初始化,一直存在到程序结束,它们的值在程序的任何地方都可以访问和修改。
这些功能在C语言中也同样适用,但在C++中并不常用。接下来介绍static面向对象的用法。
二、静态类成员
1.静态成员变量
在类中使用static关键字声明的成员变量被称为静态成员变量。这些变量属于整个类,而不是类的特定实例。因此,所有类的实例共享相同的静态成员变量。静态成员变量必须在类的定义外进行初始化。(不能在main函数中定义)
class IKUN
{
public:
static double Jage; //类内进行声明,类外进行定义
};
double IKUN::Jage = 2.5; //必须要在类外进行定义
int main()
{
IKUN j1; //实例化两个对象
IKUN j2;
j1.Jage = 3; //j1 进行修改,j2也会随之改变,
cout << "the Jage of j1:" << j1.Jage << endl;
cout << "the Jage of j2:" << j2.Jage << endl; //结果都是 3
system("pause");
return EXIT_SUCCESS;
}
在 C++ 中,当定义静态成员变量时,类内声明,类外定义的原因是:因为静态成员变量属于类的属性,而不是类的实例的属性,因此其内存空间并不随类的实例化而分配,而是在类被加载时分配,并在程序结束时释放。
2.静态成员函数
在类中使用static关键字声明的成员函数被称为静态成员函数。与普通成员函数不同,静态成员函数不与类的实例相关联,因此它们没有this指针。可以直接通过类名访问静态成员函数,而不需要创建类的实例。允许静态成员函数仅访问静态数据成员或其他静态成员函数,它们无法访问类的非静态数据成员或成员函数。
class IKUN
{
public:
static double Jage; //类内进行声明,类外进行定义
static void eat()
{
//this.m_ID; //报错,this只能用于非静态成员函数内部
cout << "my egg age is:" << Jage << endl; //可以访问静态成员变量
cout << "Let's eat fried chicken!" << endl;
}
private:
int m_ID;
};
double IKUN::Jage = 2.5; //必须要在类外进行定义
int main()
{
IKUN j1; //实例化两个对象
IKUN j2;
j1.Jage = 3; //j1 进行修改,j2也会随之改变,
//j1.eat(); //两种访问方式
IKUN::eat();//不需要实例对象,通过类名直接调用
system("pause");
return EXIT_SUCCESS;
}
与普通成员函数不同,静态成员函数没有隐含的this指针。由于没有this指针,静态成员函数无法访问实例相关的数据,因此通常用于处理与类的实例无关的任务。
总结
static的用法比较简单,也比较容易理解。今天继续复习!