标签:
Static是C++中一个常见的关键字,它被用来控制变量的存储方式和可见性。
在类定义中,它的成员(包括数据成员和成员函数)可以用关键字static申明为静态成员。静态成员的特性是不管这个类创建了多少个对象,它其中的静态成员只有一个拷贝,这个拷贝被所有属于这个类的对象共享。
从原理来分析,我们能清楚的了解,类的数据成员和成员函数都是跟着类的执行,在编译器上为他在堆栈上分配内存空间存储的。静态数据成员和静态成员函数和他们不同,它们是在程序开始运行时候存储在静态存储空间的。
在一个类中,如果将一个数据成员申明为static,这种成员就被称为静态数据成员。与一般数据成员不同的是,无论建立多少个类的对象,都只有一个静态数据成员拷贝。
首先,我们通过一个例子来分析一下静态数据成员。
1 #include "stdafx.h" 2 #include "stdlib.h" 3 4 class Student{ 5 static int count; // 申明静态数据成员,统计学生总数 6 int studentNo; // 普通数据成员,表示学生学号 7 8 public: 9 Student() 10 { 11 count++; // 每创建一个对象,学生个数加1 12 studentNo = count; // 给当前学生学号赋值 13 } 14 15 void print() 16 { 17 printf("Student%d", studentNo); 18 printf("count = %d\n", count); 19 } 20 }; 21 int Student::count = 0; // 初始化静态数据成员count 22 23 int _tmain(int argc, _TCHAR* argv[]) 24 { 25 Student Student1; // 创建第一个学生对象 26 Student1.print(); 27 printf("----------------\n"); 28 29 Student Student2; // 创建第二个学生对象 30 Student1.print(); 31 Student2.print(); 32 printf("----------------\n"); 33 34 Student Student3; // 创建第三个学生对象 35 Student1.print(); 36 Student2.print(); 37 Student3.print(); 38 39 system("pause"); 40 return 0; 41 }
上述程序的运行结果如下:
从运行结果可以看出,所有对象的count值都是相同的,这个说明他们都共享这个数据,也就是说明所有对象对于count只有一个拷贝,这就是静态数据成员的特性(作用和全局变量类似)。普通数据成员studentNo各个对象的值是不同的,所以它存放的是各个对象的对象号。
说明:
对象名.静态数据成员名;
对象名->静态数据成员名;1 class A{ 2 private: 3 static A a1; // OK 4 A *a1; // OK 5 A a3; // Error 6 };
6. 静态数据成员可以用作默认实参,而普通数据成员不可以。
1 class Example{ 2 public: 3 static int a; 4 int b; 5 6 void fun1(int i = a); // 正确,a为静态数据成员 7 void fun2(int i = b); // 错误,b为普通数据成员 8 };
7. C++支持静态数据成员的一个主要原因是可以不必使用全局变量。依赖于全局变量的类很容易违反面向对象程序的封装原理。静态数据成员的主要用途是定义类的各个对象所公用的数据,如:统计数据、平均数等。
在类定义中,在成员函数之前加上static申明成为静态成员函数。和静态数据成员一样,静态成员函数属于整个类,是该类的所有对象共享的成员函数,而不是属于某个对象特有的函数。定义静态成员函数的格式如下:
Static 返回类型 函数名(实参表)
与静态数据成员一样,它也遵循public,protect和private的原则。调用公有的静态成员函数格式如下:
类名::静态成员函数(实参表)
对象名.静态成员函数(实参表)
对象名->静态成员函数(实参表)
下面我们通过一个例子来了解静态成员函数。
1 #include "stdafx.h" 2 #include "stdlib.h" 3 4 class small_cat{ 5 private: 6 int weight; 7 static int total_weight; 8 static int totel_num; 9 public: 10 small_cat(int w) 11 { 12 weight = w; 13 total_weight += w; 14 totel_num++; 15 } 16 17 void display() 18 { 19 printf("The small cat weight %d pounds\n", weight); 20 } 21 22 static void total_disp() 23 { 24 printf("%d small cat weight ", totel_num); 25 printf(" %d pounds\n", total_weight); 26 } 27 }; 28 int small_cat::total_weight = 0; 29 int small_cat::totel_num = 0; 30 31 int _tmain(int argc, _TCHAR* argv[]) 32 { 33 small_cat w1(1),w2(3),w3(2); 34 w1.display(); 35 w2.display(); 36 w3.display(); 37 38 small_cat::total_disp(); 39 40 system("pause"); 41 return 0; 42 }
程序运行结果:
说明:
1 static void display(small_cat &w) 2 { 3 printf("The small cat weight %d pounds\n", w.weight); 4 }
静态局部变量
静态局部变量属于静态存储方式,它具有以下特点:
(1)静态局部变量在函数内定义,但不像自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序。
(2)静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后, 尽管该变量还继续存在,但不能使用它。
(3)允许对构造类静态局部量赋初值。若未赋以初值,则由系统自动赋值。数值型变量自动赋初值0,字符型变量赋空字符。
(4)对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。 根据静态局部变量的特点,可以看出它是一种生存期为整个源文件的量。虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用, 而且保存了前次被调用后留下的值。 因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用,因此仍以采用局部静态变量为宜。
标签:
原文地址:http://www.cnblogs.com/dhls231/p/static.html