一.static的使用范围
1.static可以用来修饰对象(包括基本类型,用户自定义类型。普通对象,指针对象,引用对象)
2.static可以用来修饰函数
二.static修饰对象
2.1 static修饰不同地方定义的对象
2.1.1 静态全局变量
static int a = 1;//静态全局变量
int static b = 1;//静态全局变量
int c = 1;//全局变量
const int d = 1;//常量
const static int e = 1;//常量
static const int f = 1;//常量
定义静态全局变量的时候需要加上static不能加上const
静态全局变量的可见性是文件内,不能跨文件(在另一个文件想要调用需要使用全局变量)
静态全局变量的好处:访问性比较大,同一个文件的不同地方都可以使用。可以用于函数计数等
2.1.2 静态局部变量
这里说的静态局部变量通常是值定义在函数内的变量
int main()
{
static int a = 1;//静态局部变量
int static b = 1;//静态局部变量
int c = 1;//栈中变量
const int d = 1;//栈中变量
const static int e = 1;//栈中常量
static const int f = 1;//静态局部常量
}
在函数中定义的静态局部变量内存分布将会在静态全局区,而不在栈上,不会因为函数执行完毕而被清除。
静态局部变量的好处:访问性比静态全局变量小,但是可以也可以实现函数计数的功能,同时因为静态的原因,只会在程序初始化的时候分配一次内存
代码辨析:
#include<iostream>
using namespace std;
static int a = 1;
int static b = 1;
int c = 1;
const int d = 1;
const static int e = 1;
static const int f = 1;
void test()
{
printf("\n");
printf("%d",a);
printf("%d",b);
printf("%d",c);
}
int main()
{
static int a = 2;
int static b = 2;
int c = 2;
const int d = 2;
const static int e = 2;
static const int f = 2;
printf("%d",a);
printf("%d",b);
printf("%d",c);
printf("%d",d);
printf("%d",e);
a++;
b++;
c++;
test();
printf("\n");
printf("%d",a);
printf("%d",b);
printf("%d",c);
}
分析:我们发现,我们在定义了相同名称的静态全局变量和静态局部变量,我们访问他们的方式如下:
在本函数内查找,如果没有找到则会去函数外查找(不包括上一级函数,所有函数外!)
三.static修饰成员函数和成员变量
3.1 修饰成员变量
class A
{
static int a;
public:
A()
{
a=0;
//this.a=0;编译报错
}
};
分析:当我们将成员变量定义成static 它就不在只属于这个对象,而是被所有类对象共享(可以进行通信了!)。如果我们要进行
如果我们这么写
static int a = 0;///编译报错,forbids in-class initialization of non-const static member不能在类内初始化非const static成员
为什么我们不能在类中设定值呢?
C++标准只允许static constant intergral或者枚举类型的数据在类内进行初始化。
为什么标准不允许这一行为?
C++需要每一个对象有特定的定义。如果C++允许存储在内存中的对象进行类内定义,那么这一规则将会被打破。(C++不希望对象去定义类,而是由类的定义生成对象)
那我们怎样初始化呢?
1.将static 修改成 static const,这样编译器会为我们开一个后门,因为它不在会改变。
2.进行类外定义(如果是私有的怎么办,调用公共的static成员函数)
如何在类外定义呢?
class A
{
public :
static int a;
A()
{
a=0;
//this.a=0;编译报错
}
};
int A::a = 1; //类外定义,我们用 类型名称 类名称::变量名 = 值;去进行类外定义。
int main()
{
}
3.2 static修饰成员函数
首先static修饰成员函数的时候还是有一些限制
不能修饰构造函数
不能修饰析构函数
不能修饰拷贝构造函数
不能修饰操作符重载函数(static可以修饰非成员函数的操作符重载,static几乎没用)
不能修饰虚函数
不能修饰纯虚函数
关于静态成员函数的继承问题(静态函数是可以被继承的)
静态成员函数只能访问静态成员变量不能访问其他成员变量
四.关于static 的一些特殊情况
union中可以定义静态函数,但是union中不能定义静态成员变量所以几乎没什么用