当我们在自己编写或阅读他人写的代码时,经常会遇到“static”关键字,本文将对“static”关键字涉及的知识点加以总结。
1、static关键字的应用场景
总体来说,主要应用于以下5个场景:
面向过程:(1)声明静态局部变量 (2)声明静态全局变量 (3)声明静态函数
面向对象:(4)声明类的静态成员变量 (5)声明类的静态成员函数
2、static关键字应用详解
在文章c++内存管理中,详细介绍了C++对于计算机的内存分配及使用。那么,经过static关键字成功修饰的变量,都存放于静态数据区(也叫全局数据区)中。
2.1 静态局部变量
(1)在局部变量前加上“static”关键字,就变为静态的局部变量;
(2)一般在函数体内声明、定义,作用域为函数内部或语句块;
(3)默认初始值为0,声明和定义只被运行一次,以后再调用静态局部变量所在的函数时,会跳过声明和定义;
(4)存放于全局数据区(静态数据区)。
C++程序举例,程序运行结果及说明在注释中给出
#include<iostream>
using namespace std;
void staticTest()
{
static int static_local_value; //声明静态局部变量,默认初始值为0,作用域为函数内部
static_local_value++;
cout<<"静态整型局部变量的值为: "<<static_local_value<<endl;
}
void normFunc()
{
cout<<"试图访问静态局部变量"<<static_local_value<<endl; //程序报错,因为static_local_value的作用域为staticTest()函数内部
int norm_value=0;
norm_value++;
cout<<"整型局部变量的值为: "<<norm_value<<endl;
}
int main()
{
normFunc(); //输出结果为1
normFunc(); //输出结果为1
normFunc(); //输出结果为1
staticTest(); //输出结果为1
staticTest(); //输出结果为2,再次调用staticTest()函数时,会跳过static_local_value的定义
staticTest(); //输出结果为3
return 0;
}
2.2 静态全局变量
特点:
(1)在全局变量前加上“static”关键字即可变为静态全局变量,默认初值为0;
(2)作用域位于整个程序文件,但不能被其他程序文件访问;
(3)存放于静态数据区(也叫全局数据区)。
C++程序举例,程序运行结果及解释在注释中给出:
"在文件1.cpp中"
#include<iostream>
using namespace std;
void file2Func(); //在文件2中定义函数file2Func()
static int static_global_value; //静态全局变量,默认初值为0
int global_value=0; //全局变量
void staticTest()
{
static_global_value++;
global_value++;
cout<<"文件1中,静态全局变量的值为: "<<static_global_value<<endl;
cout<<"全局变量的值为: "<<global_value<<endl;
}
int main()
{
staticTest();
file2Func();
return 0;
}
"在文件2.cpp中"
#include<iostream>
using namespace std;
extern int global_value;
extern int static_global_value;
void file2Func()
{
cout<<"文件2中,全局变量为: "<<global_value<<endl;
cout<<"全局静态变量为: "<<static_gloabl_value>>endl; //程序报错,无法访问static_global_value
}
2.3 静态函数
(1)在普通函数前加上static关键字;
(2)静态函数的作用域仅限在本程序文件中,其他文件中无法访问;
(3)从而在其他文件中可以存在与静态函数同名的函数,且不会引起冲突;
C++程序举例:
"在文件1.cpp中"
#include<iostream>
using namespace std;
static void file2StaticFunc(); //文件2.cpp中的静态函数
void normFunc(); //文件2中的普通函数
void static staticFunc()
{
cout<<"访问文件1中的静态函数。"<<endl;
}
int main()
{
staticFunc(); //程序正常运行
normFunc(); //程序正常运行
file2StaticFunc(); //程序报错,无file2StaticFunc()的定义
return 0;
}
"在文件2.cpp中"
#include<iostream>
using namespace std;
void file2StaticFunc()
{
cout<<"访问文件2中的静态函数。"<<endl;
}
void normFunc()
{
cout<<"访问文件2中的普通函数。"<<endl;
}
2.4 类的静态成员变量
(1)在类的成员变量前加上“static”关键字;
(2)在类内声明,可以是public、private或protected成员,访问权限与普通成员变量相同;
(3)在类外定义,利用<变量类型> <类名>::<变量名>=<变量值>定义;
(4)类的静态成员变量是输入整个类的,为所有类的对象所共有,可以通过”类名::类的静态成员变量名”来访问;
(5)存放在静态数据区;
2.5 类的静态成员函数
(1)没有this指针,为类的所有对象所共有;
(2)只能访问类中的静态成员变量和静态成员函数,而不能访问非静态成员变量和非静态成员函数;
(3)类的非静态成员函数可以调用静态成员变量和静态成员函数;
(4)可以通过“类名::函数名”来访问。
针对2.4和2.5两种情形,下面用c++语言举例说明:
"在testStatic.h文件中"
#include<iostream>
using namespace std;
class testStatic{
public:
testStatic(int temp); //构造函数
~testStatic(){} //析构函数
static int static_value; //声明共有类型的静态成员变量
void coutNum()
{
static_value++;
cout<<"静态成员变量的值为: "<<static_value<<endl;
}
static void staticFunc() //静态成员函数
{
cout<<++static_value<<endl;
//cout<<"访问整型成员变量: "<<normValue<<endl; //出错,静态成员函数不能访问非静态变量
}
private:
int normValue;
};
int testStatic::static_value=5; //静态成员变量定义
testStatic::testStatic(int temp)
{
normValue=temp;
}
"在文件main.cpp中"
#include"testStatic.h"
#include<iostream>
using namespace std;
int main()
{
testStatic test1(3),test2(4),test3(5);
test1.coutNum(); //输出静态成员变量为:6
test2.coutNum(); //输出静态成员变量为:7
test3.coutNum(); //输出静态成员变量为:8
cout<<test1.static_value<<endl; //输出8,因为static_value为public类型
cout<<testStatic::static_value<<endl; //输出8,因为static_value为类的静态成员变量
test1.staticFunc(); //输出9,可以利用类的任一对象访问静态成员函数
test2.staticFunc(); //输出10
testStatic::staticFunc(); //输出11,可以通过类名访问静态成员函数
}