C++对象生存期&&static
生存期,即从诞生到消失的时间段,在生存期内,对象的值或保持不变,知道改变他的值为止。对象生存期分为静态生存期和动态生存期两种。
- 静态生存期
指对象的生存期与程序运行期相同。在namespace中声明的对象都具有静态生存期。但是,在函数内部作用域中声明具有动态生存期的对象,要用static修饰,如static int a。
在局部作用域中,静态变量的特点是不会随函数的每次调用而产生一个副本,同时也不会因为函数的返回而消失。该变量会一直保持上一个值,在每次调用中可共享。同时静态变量在定义时也可以赋值,如static int a = 3;
- 动态生存期
除上述两种情况,其余为动态生存期。在局部作用域中,有动态生存期的对象,也称为局部生存期对象。局部生存期对象诞生于声明点,结束于声明块执行完毕。在类中不用static修饰的成员,他们的生存期和对象生存期一致。
例:
#include<iostream> using namespace std; int i =1;//i全局变量,动态生存期 void Other() { static int a = 2; static int b ;//a,b为静态局部变量,全局寿命,局部可见,第一次进入函数时初始化 int c = 10;//c局部变量,动态生存期,每次进入函数都初始化 a+=2; i+=32; c+=5; cout<<"Other:"<<endl; cout<<"i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl; } int main() { static int a;//静态局部变量,全局寿命,局部可见 int b= -1; int c = 0;;//b,c局部变量,动态生存期 cout<<"Main:"<<endl; cout<<"i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl; c+=8; Other(); cout<<"Main:"<<endl; cout<<"i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl; i+=10; Other(); return 0; }
运行结果
类的静态成员
类的静态成员是解决同一个类的不同对象之间数据和函数的共享问题的。如每生成一个对象,则计数+1,从而统计一共创建了多少个对象。
- 静态数据成员
在类的一个属性中,如果某个属性为整个类所共享,则用static修饰为静态成员。该成员在每个类中只有一个副本,由所有对象共同维护,从而实现数据共享。
静态数据成员具有静态生存期,因为静态数据成员不属于任何对象,可以这么访问,”类名::成员名 | 对象名.成员名 | 指针->成员名 | 引用.成员名“ 。另外,在类定义中,仅进行引用性声明,而在namespace作用域中使用类名限定定义性声明,或初始化。(原因:这样定义是因为这种方式要专门分配空间,非静态数据成员的空间与所属对象空间是同时分配的,所以无须这样定义)。
例:
#include<iostream> using namespace std; class Point { public: Point(int x = 0,int y = 0):x(x),y(y) { count++; } Point(Point &p)//copy { x = p.x; y = p.y; count++; } ~Point() { count --; } int GetX(){return x;} int GetY(){return y;} void ShowCount()//静态函数 { cout<<"Object count :"<<count<<endl; } private: static int count;//static int x; int y; }; int Point:: count = 0;//静态数据成员的初始化,类名限定 int main() { Point a(4,5); cout<<"Pont a:"<<"("<<a.GetX()<<","<<a.GetY()<<")"<<endl; a.ShowCount();//通过对象名 Point b(a); cout<<"Pont b:"<<"("<<b.GetX()<<","<<b.GetY()<<")"<<endl; b.ShowCount(); return 0; }
运行结果
- 静态函数成员
在上面例子中,ShowCount()是输出count的值的,而在所有对象声明前,count是==0的,那么如果输出这时的count,该怎么做??所以这时静态函数成员就起作用了。
修改如下:
class Point { public: . . . static void ShowCount()//静态函数 { cout<<"Object count :"<<count<<endl; } private: ... }; int Point:: count = 0;//静态数据成员的初始化,类名限定 int main() { Point::ShowCount(); Point a(4,5); cout<<"Pont a:"<<"("<<a.GetX()<<","<<a.GetY()<<")"<<endl; Point::ShowCount(); Point b(a); cout<<"Pont b:"<<"("<<b.GetX()<<","<<b.GetY()<<")"<<endl; Point::ShowCount(); return 0; }
运行结果
在ShowPoint()函数前加一个static,即变为静态成员函数,它也属于整个类,有所有对象共同拥有,为所有对象共享。静态成员函数可以用过类名|对象名访问,非静态成员函数只能通过对象名调用。
另外,静态成员函数可以直接访问类的静态数据和函数成员,而访问非静态成员,必须通过对象名。所以一般情况下,静态函数用来访问类的静态数据成员。