面向过程设计中的static
1、静态全局变量
在全局变量前加static,该全局变量为静态全局变量,只能在当前文件中(就是当前cpp文件中)使用,别的cpp文件如果用extern来声明存在这样一个变量,则在链接时会提示无法解析外部符号。
例:
//a.cpp
static int a;
//b.cpp
exterin int a;
int main()
{
a = 1;
}
报错,无法解析外部符号a。
2、静态局部变量
在局部变量前,加关键字static,改变量就为静态局部变量,同样的,全局数据区中的内存也只分配一次;其作用域为局部作用域,在函数返回后或语句块结束时,作用域也结束。
已初始化的的全局变量和局部静态变量存放在.data段,未初始化的全局变量和局部静态变量一般存放在.bss段里,前者在生产可执行文件时就分配好内存了,后者在加载时才分配这段话说的对不对?
3、静态函数
在函数返回类型(定义或者声明中任意一个)前加static,函数即定义为静态函数,该函数不可以被其他文件引用。
例:
//a.cpp
#include"iostream"
using namespace std;
static void funA();
void funA()
{
cout<<"FUNA"<<endl;
}
//b.cpp
void funA();
int main()
{
funA();
}
程序会报错“无法解析外部函数funA()”。在b.cpp文件中声明funA函数时没有加extern,这是因为有些编译器(不确定是不是全部?)会自动将所有函数默认为extern类型(就如变量会默认为auto类型)。上述程序只要将static去掉即可正常运行。在函数编译完成,生成a.obj,b.obj后,链接器将他们链接成为可执行文件。平时编写cpp文件时,习惯将函数声明放在头文件中,然后其他cpp文件需要用到这里的函数时,只要包含头文件即可,这其实就是省去了在其他cpp文件中声明一遍外部函数的过程(include自动把函数的声明都包含进去了),事实上不用include头文件,自己非要写一遍声明,外部函数也是可以用的,就如上例。
面向对象的static关键字
1、静态成员变量
在类的声明内,变量的声明前加上static,该变量就为静态成员变量,其特点是,相对于非静态成员变量在每个对象中都有自己的拷贝,静态成员变量在程序中只有一份,被该类所有的对象所共享,故它必须在类外声明,以在全局变量区分配内存并初始化(也可以这样理解,如果它是在对象实例定义的时候被分配内存,岂不是每一个对象都有一个该静态变量的拷贝了?)其初始化格式为 数据类型 类名::静态成员变量名 = XXX
例:
#include <iostream>
using namespace std;
class Myclass
{
public:
Myclass(int a,int b,int c);
void GetSum();
private:
int a,b,c;
static int Sum;//声明静态数据成员
};
int Myclass::Sum=0;//定义并初始化静态数据成员,必须在类的声明外做,声明内是不能分配内存的
Myclass::Myclass(int a,int b,int c)
{
this->a=a;
this->b=b;
this->c=c;
Sum+=a+b+c;
}
void Myclass::GetSum()
{
cout<<"Sum="<<Sum<<endl;
}
void main()
{
Myclass M(1,2,3);
M.GetSum();
Myclass N(4,5,6);
N.GetSum();
}
输出结果 Sum=6 Sum = 21
同时由于静态成员变量不属于某一个对象,因此在没有对象实例时,如果静态成员变量是public成员就可以对他进行操作。
有两种访问形式
类名::静态成员变量名
类的对象名.静态成员变量名
2、静态成员函数
静态成员函数只能访问同一类的静态成员变量,而不可以调用类的非静态成员,这是因为静态成员函数没有this指针。
需要注意的是,静态成员函数只可以声明在类的声明中(static关键字只能出现在类的声明中)
例如
class A{
void foo()
}
static A::foo()//报错
{
}
同时,静态成员函数也只能调用静态成员函数,而不能调用非静态成员函数。
另外,静态成员函数的地址可以用普通函数指针存储,而普通成员函数的地址需要用类成员函数指针来储存。举例如下:
class base{
static int func1();
int func2();
};
int (*pf1)()=&base::func1;//普通的函数指针
int (base::*pf2)()=&base::func2;//成员函数指针