在c++中,不仅支持传统C语言中static的特性,如:全局静态函数,局部静态变量,静态函数等,还对static进行了扩展,支持静态数据成员,静态函数成员,静态对象等。
一:static变量的常见应用
1:静态局部变量和普通局部变量的区别:
它们的主要区别是作用域不同,静态局部变量的是包含它当前的源文件,该工程的其他源文件是不可以访问它的。这样做的好处是多人联合开发时,不必担心变量名冲突问题。而普通局部变量的的作用域是当前的整个工程,整个工程里的不同文件可以共享全局变量。
两者都存放在全局数据区,如果没有初始化,系统将其自动初始化为0。
2:静态局部变量和普通局部变量的区别:
(1):存储位置不同:
静态局部变量被static修饰,其生命周期是全局的,在整个源文件执行完毕后释放,而不会在某个当前函数执行完就释放,所以说静态局部变量存储在全局数据区。由于整个生命周期是全局的,所以对其初始化只会执行一次,后面遇到的合法初始化也会自动跳过。但是其作用域还是局部的,在其作用域外不可以被调用。
普通局部变量存放在堆栈中,随函数执行完毕后自动释放。
(2):默认初始值不同,静态局部变量默认初始值为0,但其如果人为初始化只执行一次,后面的初始化都不会再执行。而普通局部变量初始值随机,但是每一次合法初始化都会执行。
#include
#include
int a; //全局变量
int main()
{
int b; //局部变量,栈变量
int *c=(int *)malloc( sizeof(int) ); //局部变量,堆变量
printf("%d,%d\n",a,b);
return 0;
}
执行结果为:
可以看到将全局变量自动初始化为0,而局部变量则随机初始化。
(3):静态函数和普通函数:
静态函数的作用域为当前的源文件,而局部函数的作用域为整个工程。但是静态函数会被一直放在一个一直使用的存储区,直到退出应用程序实列,避免了调用函数时的压栈和出栈,速度快很多。
(4):static传统应用实例
#include
using namespace std;
static int a;
static void fun();
int main()
{
fun();
cout << "main:a=" << a << endl;
fun();
return 0;
}
static void fun()
{
static int a=10;
int b=20;
a*=10;
b*=20;
cout << "fun:a=" << a <<",b=" << b << endl;
}
执行结果为:
我们可以看到静态函数真的只初始化一次,而普通函数可以多次初始化。且普通全局变量默认为0。
二:static在c++中的扩展
1:静态数据成员:
静态数据成员是属于整个类的,而不是属于某个对象。即不管实例多少个对象,它们都公用一个静态数据成员。
静态数据成员的初始化,在c++中,普通数据成员在构造函数的函数体或初始化表中初始化;常量数据成员(const int a )必须在构造函数的初始化表中初始化;而静态数据成员(static int b )则必须在类外初始化(int 类名::b=100),这是因为静态数据成员不属于任何一个对象,而是属于整个类的。
静态数据成员存储在全局数据区,且必须初始化才可以使用,不能在类声明中初始化。这是因为静态数据成员的生命周期比一个具体的类对象更长一些,在类对象存在之前就已经存在。也就是说程序一启动就可能要使用到静态成员变量,所以一开始就需要初始化。如果不在类外赋初值,之自动初始化为0。
#include
using namespace std;
class leikun
{
private:
static int a;
static int b;
public:
void show()
{
cout << "a=" << a << endl;
cout << "b=" << b << endl;
}
};
int leikun::a=100;
int leikun::b;
int main()
{
leikun b;
b.show();
return 0;
}
运行结果为:
2:静态成员函数
静态成员函数也是属于整个类的,但是不属于任何一个对象。它是某个类所有对象共享的一个函数。普通的成员函数都有一个this指针,this指针用来指向类的对象本身。因为静态成员函数不属于任何对象,所以静态数据成员函数并没有this指针,所以它无法来访问普通的数据成员,它只能调用其余的静态成员。
静态成员函数可以被该类的所有对象直接访问;静态成员函数本身只能访问静态成员,不可以访问非静态成员。