static关键字最常见的用法是定义静态变量
静态变量有静态全局变量和静态局部变量,这两种变量的生存周期是整个程序的运行时间。二者的左右域不同,静态全局变量作用域是本文件内,静态局部变量的作用域是变量所在的局部代码块中。
- 静态全局变量
与普通全局变量不同,静态全局变量只能在本文件中使用,其他文件不可见。这样可以在多个文件中命名冲突的问题,例:
//static_pratice.h
#ifndef _STATIC_PRACTICE_
#define _STATIC_PRACTICE_
int sum(int a,int b);
int sub(int a,int b);
#endif
//sub.cpp
static int res;
int sub(int a,int b){
res = a-b;
return res;
}
//sum.cpp
static int res;
int sum(int a,int b){
res = a + b;
return res;
}
//main.cpp
#include "static_practice.h"
#include "stdio.h"
static int res = 100;
void main(){
printf("sum = %d\n",sum(10,5));
printf("sub = %d\n",sub(10,5));
printf("res = %d\n",res);
}
结果:
可以看到在sub.cpp、sum.cpp和main.cpp中都定义了名字叫res的变量,但链接时并没有报变量重定义的错误。若在任意两个文件中定义res是不是用static关键字,则在链接时会报变量重定义的错误,在此就不举错误的例子了。
- 静态局部变量
静态局部变量与普通局部变量相比,主要区别在于生存周期。前者的生存周期是整个程序的运行过程,后者的生存周期是局部代码块(最好理解的代码块就是函数)的运行过程,需要注意的是静态局部变量只会初始化一次(有点像在循环里定义一个变量)。这里要注意生存周期和作用域的区别,例:
#include <stdio.h>
int fac(int n){
static int count = 0;
count++;
printf("%d",count);
if(1 == n){
return 1;
}
printf("*");
return n*fac(n-1);
}
void main(){
printf(" = %d\n",fac(5));
}
结果:
这里用到一个递归,在fac中定义的count在每次函数递归调用本身时都会自加一次,这里可以说明count的初始化语句只执行了一次。
static还可以实现单例模式,具体如下:
#include <iostream>
using namespace std;
class A{
public:
A(){isInit = false;}
~A(){}
static A* GetInstance();
void Init(int data);
int Getdata();
private:
int data;
bool isInit;
};
A* A::GetInstance(){
static A *a = new A();
return a;
}
void A::Init(int data){
if(false == isInit){
this->data = data;
isInit = true;
}
}
int A::Getdata(){
return data;
}
void main(){
A* b = A::GetInstance();
b->Init(3);
A* c = A::GetInstance();
cout << c->Getdata() <<endl;
cout << b->Getdata() <<endl;
}
结果:
在单例模式中用到了C++面相对象编程中的static成员函数,static成员函数属于某一个类而非某一对象,所以不能通过实例对象调用,而是需要通过类名直接调用。