详解C语言(C++)中的static关键字
static是C++中常用的关键字之一,意思是静态,可以修饰变量,static修饰的变量永远只初始化一次,也可以修饰函数,接下来我们就详细来讨论一下static:
- 静态局部变量
- 静态全局变量
- 静态成员变量
- 静态函数
- 静态成员函数
静态局部变量
static可以用来修饰局部变量,定义的语句永远只执行一次,生命周期为全局,可见性为局部,存储在静态存储区中。
示例代码:
#include "stdafx.h"
#include <iostream>
using namespace std;
void fun()
{
static int nNum = 0;//定义一个静态局部变量
nNum++;
cout << "nNum : "<<nNum << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
for (int i = 0; i < 10; i++)
{
fun(); //循环调用函数,观察打印结果
}
return 0;
}
运行结果:
静态全局变量
static修饰全局变量时,生命周期为全局,可见性为当前文件,存储在静态存储区中。
示例代码:
#include "stdafx.h"
#include <iostream>
using namespace std;
static int g_nStaticNum = 10;
int g_nNum = 10;
void fun()
{
cout << "g_nStaticNum :" << g_nStaticNum << endl; //静态全局变量
cout << "g_nNum :" << g_nNum << endl; //全部变量
}
int _tmain(int argc, _TCHAR* argv[])
{
cout << "g_nStaticNum :" << g_nStaticNum << endl; //静态全局变量
cout << "g_nNum :" << g_nNum << endl; //全部变量
g_nStaticNum++; //静态全局变量
g_nNum++; //全部变量
fun();
return 0;
}
运行结果:
结果说明:
大家可以看到,我在代码中定义了两个全局变量,一个是静态全局变量,一个是普通全局变量,两者输出结果完全一致!那为什么还要有静态全局变量呢?我们一起来看下下面这个面试题。
问: 静态全局变量和全局变量有什么区别?
答: 可见性不同(能回答这句话就差不多了)。首先静态全局变量和全局变量都存储在静态存储区,声明周期都是全局的,其中全局变量的可见性为整个工程,也就是说在其他.c或者.cpp文件中通过extern声明后,便可以使用,而静态全局变量只在本文件中可用,对其他文件不可见。
小结: 如果你不想全局变量被其他文件中的函数或类调用,或者担心在其他文件中不小心改变而引发不必要的错误,则可以使用static来修饰该全局变量。
静态数据成员
静态数据成员主要注意的地方是初始化,需要在类外进行初始化,并且在多个实例中也只存在一份,静态数据成员可以被继承,但也永远只有一份,可能这么解释大家也不是很明白,看下面的代码你就很清楚啦~
示例代码:
#include "stdafx.h"
#include <iostream>
using namespace std;
class CA
{
public:
CA(){ m_nCount++; } //构造时计数加1
~CA(){}
public:
static int m_nCount; //记录类(和子类)被实例化的总次数
};
int CA::m_nCount = 0; //初始化静态成员变量
//CB继承了CA,m_nCount被继承,但整个程序中永远只有一份
class CB : public CA
{
public:
CB(){}
~CB(){}
};
int _tmain(int argc, _TCHAR* argv[])
{
//类没有实例化时,静态成员变量可以直接通过::运算符调用
cout << "静态成员变量:"<< CA::m_nCount << endl;
cout << "******************定义3个CA的实例***************" << endl;
CA A1;
CA A2;
CA A3;
cout << "CA::m_nCount : " << CA::m_nCount << endl;
cout << "*****************再定义2个CB的实例**************" << endl;
CB B1;
CB B2;
cout << "CA::m_nCount : " << CA::m_nCount << endl;
cout << "CB::m_nCount : " << CB::m_nCount << endl;
return 0;
}
运行结果:
静态函数
静态函数只能在本源文件中使用,如果函数只在本源文件中使用,想对其他文件不可见的情况下,可以使用static修饰。其他的就不再过多的解释,有兴趣的小伙伴可以自己在代码中尝试哦~
示例代码:
#include "stdafx.h"
#include <iostream>
using namespace std;
static void StaticFun()
{
cout << "This is a static function!" << endl;
};
int _tmain(int argc, _TCHAR* argv[])
{
StaticFun(); //使用方法与普通函数相同
return 0;
}
运行结果:
静态成员函数
1.生命周期为全局,可以在对象为创建时,使用类域::调用该成员函数。
2.静态成员函数无this指针,因此静态成员函数内部不可调用非静态成员变量及函数(如有其他疑问请留言)。
用例:可以使用static静态成员函数实现单例模式(后续的文章会单独讲解)
示例代码:
#include "stdafx.h"
#include <iostream>
using namespace std;
class CA
{
public:
CA(){ m_nData = 0; }
~CA(){}
public:
static void Fun();//静态成员函数
static int m_nNum;
private:
int m_nData;
};
int CA::m_nNum = 10; //静态成员在类外初始化
void CA::Fun() //函数定义时不需要加static
{
cout << "这里是静态成员函数" << endl;
cout << "CA::m_nNum :" << CA::m_nNum << endl;//可以调用静态成员函数
//cout << m_nData << endl;//不能调用非静态成员函数或成员变量
}
int _tmain(int argc, _TCHAR* argv[])
{
CA::Fun();//静态成员函数可以直接通过类域调用
return 0;
}
运行结果:
结束语
初入博客界,请大家不喜勿喷!如发现文中有错误或不足之处,还请大家直接指出,博主会第一时间修正!我会继续努力的!