1.首先介绍一下C语言中的static,有三种
- 静态局部变量:用于函数体内部修饰变量,这种变量的生存期长于该函数。
#include<stdio.h>
int fun(){
static int i = 1;
i += 1;
return i;
}
int main(){
printf("%d\n",fun());
printf("%d\n",fun());
return 0;
}
变量i一直存放在静态区,在程序运行之初就开辟了一块静态内存空间,每调用一次fun()函数,都会在原来的基础上再加一,而不是再次进行初始化。
2.静态全局变量:定义在函数体外,用于修饰全局变量,表示该变量只在本文件可见。
#include<stdio.h>
static int i = 10;
int fun(){
i += 1;
return i;
}
int main(){
printf("%d\n",fun());
printf("%d\n",fun());
return 0;
}
3.静态函数:准确的说,静态函数跟静态全局变量的作用类似:
#include<stdio.h>
static int i = 10;
static int fun(){
int i = 10;
i += 1;
return i;
}
int main(){
printf("%d\n",fun());
printf("%d\n",fun());
return 0;
}
1.静态函数不能被其它文件所用;
2.其它文件中可以定义相同名字的函数,不会发生冲突;
2.C++ 语言的 static 关键字有二种用途:
1.静态数据成员:用于修饰 class 的数据成员,即所谓“静态成员”。这种数据成员的生存期大于 class 的对象(实体 instance)。静态数据成员是每个 class 有一份,普通数据成员是每个 instance 有一份,因此静态数据成员也叫做类变量,而普通数据成员也叫做实例变量。
静态数据成员可以为私有,也可以为公有。
对于非静态数据成员,每个类对象(实例)都有自己的拷贝。而静态数据成员被当作是类的成员,由该类型的所有对象共享访问,对该类的多个对象来说,静态数据成员只分配一次内存。
#include<iostream>
using namespace std;
class student{
private:
int m_a;
int m_b;
public:
static int m_c;
student(int a,int b){
m_a = a;
m_b = b;
}
int getc(){
m_c++;
return m_c;
}
//static修饰的静态成员变量
//可以私有,也可以公有
};
//静态成员变量的初始化,一定要在类的外边
//这个变量在静态区,对整个类共享
int student::m_c = 100;
int main(){
student s1(10,20);
student s2(100,200);
cout << s1.getc() << endl;
cout << s2.getc() << endl;
s1.m_c = 200;
s2.m_c = 200;
student::m_c = 200; //此句成功的前提是m_c为公有,若为私有,只能通过以上两句来访问m_c
//以上三句访问的是同一个空间,也就是m_c的空间
cout << s1.getc() << endl;
cout << s2.getc() << endl;
return 0;
}
因为所有的对象共用静态数据变量,所以如果想要访问并修改静态变量的值,只需任选一个对象对其进行修改即可
s1.m_c = 200;
s2.m_c = 200;
如果静态变量为公有,还可以通过类名进行访问并修改
student::m_c = 200;
2、静态成员函数:用于修饰 class 的成员函数。
#include<iostream>
using namespace std;
class student{
private:
int m_a;
int m_b;
public:
student(int a,int b){
m_a = a;
m_b = b;
}
int getc(){
m_c++;
return m_c;
}
static int& getCc(){
return m_c;
}
//static修饰的静态成员变量
//可以私有,也可以公有
static int m_c;
};
//静态成员变量的初始化,一定要在类的外边
//这个变量在静态区,对整个类共享
int student::m_c = 100;
int main(){
student s1(10,20);
student s2(100,200);
cout << s1.getc() << endl;
cout << s2.getc() << endl;
s1.m_c = 200;
s2.m_c = 200;
student::m_c = 200; //此句成功的前提是m_c为公有,若为私有,只能通过以上两句来访问m_c
//以上三句访问的是同一个空间,也就是m_c的空间
cout << s1.getc() << endl;
cout << s2.getc() << endl;
s1.getCc() = 300;
student::getCc() = 300;
//如果想要 返回一个静态成员,需要写一个静态成员方法 ,如果需要通过此方法修改静态变量的值,所以需要用到引用
cout << s1.getc() << endl;
cout << s2.getc() << endl;
return 0;
}
对getCc()加上static,使它变成一个静态成员函数,可以用类名::函数名进行访问,也可以通过任意一个对象名进行访问。
如果想要修改静态成员函数对应的返回值,用引用即可。
那么静态成员函数有特点呢?
1.静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;
2.非静态成员函数可以任意地访问静态成员函数和静态数据成员;
3.静态成员函数不能访问非静态成员函数和非静态数据成员;
4.调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以用类名::函数名调用(因为他本来就是属于类的,用类名调用很正常)
前三点其实是一点:静态成员函数不能访问非静态(包括成员函数和数据成员),但是非静态可以访问静态,有点晕吗?没关系,我给你个解释,
因为静态是属于类的,它是不知道你创建了10个还是100个对象,所以它对你对象的函数或者数据是一无所知的,所以它没办法调用,而反过来,你创建的对象是对类一清二楚的(不然你怎么从它那里实例化呢),所以你是可以调用类函数和类成员的。