标签:style class blog code java http
http://blog.csdn.net/hackbuteer1/article/details/7487694
c++中static有种使用方式:面向过程的static,面向对象的static。前者用于普通变量或函数,不涉及类。而后者出现在类中。
一:面向过程的static ,
1、静态全局变量
在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量。我们先举一个静态全局变量的例子,如下:
1 #include<iostream> 2 using namespace std; 3 4 static int n; //定义静态全局变量 5 6 void fn() 7 { 8 n++; 9 cout<<n<<endl; 10 } 11 12 int main(void) 13 { 14 n = 20; 15 cout<<n<<endl; 16 fn(); 17 return 0; 18 }
静态全局变量有以下特点:
静态变量都在全局数据区分配内存,包括后面将要提到的静态局部变量。对于一个完整的程序,在内存中的分布情况如下图:
代码区 |
全局数据区 |
堆区 |
栈区 |
一般程序的由new产生的动态数据存放在堆区,函数内部的自动变量存放在栈区。自动变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静态局部变量)也存放在全局数据区。全局数据区的数据并不会因为函数的退出而释放空间。细心的读者可能会发现,Example 1中的代码中将
改为
程序照样正常运行。
的确,定义全局变量就可以实现变量在文件中的共享,但定义静态全局变量还有以下好处:
静态全局变量不能被其它文件所用;
其它文件中可以定义相同名字的变量,不会发生冲突;
您可以将上述示例代码改为如下:
1 //File1 2 #include<iostream> 3 using namespace std; 4 5 void fn(); 6 static int n; //定义静态全局变量 7 8 int main(void) 9 { 10 n = 20; 11 cout<<n<<endl; 12 fn(); 13 return 0; 14 } 15 16 //File2 17 #include<iostream> 18 using namespace std; 19 20 extern int n; 21 22 void fn() 23 { 24 n++; 25 cout<<n<<endl; 26 }
编译并运行这个程序,您就会发现上述代码可以分别通过编译,但运行时出现错误。试着将
static int n; //定义静态全局变量
改为
int n; //定义全局变量
再次编译运行程序,细心体会全局变量和静态全局变量的区别。
2、静态局部变量
在局部变量前,加上关键字static,该变量就被定义成为一个静态局部变量。
我们先举一个静态局部变量的例子,如下:
#include<iostream> using namespace std; void fn(); int main(void) { fn(); fn(); fn(); return 0; } void fn() { static int n = 10; cout<<n<<endl; n++; }
通常,在函数体内定义了一个变量,每当程序运行到该语句时都会给该局部变量分配栈内存。但随着程序退出函数体,系统就会收回栈内存,局部变量也相应失效。
但有时候我们需要在两次调用之间对变量的值进行保存。通常的想法是定义一个全局变量来实现。但这样一来,变量已经不再属于函数本身了,不再仅受函数的控制,给程序的维护带来不便。
静态局部变量正好可以解决这个问题。静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。
静态局部变量有以下特点:
(1)该变量在全局数据区分配内存;
(2)静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化;
(3)静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0;
(4)它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束;
3、静态函数
在函数的返回类型前加上static关键字,函数即被定义为静态函数。静态函数与普通函数不同,它只能在声明它的文件当中可见,不能被其它文件使用。
静态函数的例子:
1 #include<iostream> 2 using namespace std; 3 4 static void fn(); //声明静态函数 5 6 int main(void) 7 { 8 fn(); 9 return 0; 10 } 11 12 void fn() //定义静态函数 13 { 14 int n = 10; 15 cout<<n<<endl; 16 }
定义静态函数的好处:
静态函数不能被其它文件所用;
其它文件中可以定义相同名字的函数,不会发生冲突;
二、面向对象的static关键字(类中的static关键字)
1、静态数据成员
在类内数据成员的声明前加上关键字static,该数据成员就是类内的静态数据成员。先举一个静态数据成员的例子。
1 #include<iostream> 2 using namespace std; 3 4 class Myclass 5 { 6 private: 7 int a , b , c; 8 static int sum; //声明静态数据成员 9 public: 10 Myclass(int a , int b , int c); 11 void GetSum(); 12 }; 13 14 int Myclass::sum = 0; //定义并初始化静态数据成员 15 16 Myclass::Myclass(int a , int b , int c) 17 { 18 this->a = a; 19 this->b = b; 20 this->c = c; 21 sum += a+b+c; 22 } 23 void Myclass::GetSum() 24 { 25 cout<<"sum="<<sum<<endl; 26 } 27 28 int main(void) 29 { 30 Myclass M(1 , 2 , 3); 31 M.GetSum(); 32 Myclass N(4 , 5 , 6); 33 N.GetSum(); 34 M.GetSum(); 35 return 0; 36 }
可以看出,静态数据成员有以下特点:
2、静态成员函数
与静态数据成员一样,我们也可以创建一个静态成员函数,它为类的全部服务而不是为某一个类的具体对象服务。静态成员函数与静态数据成员一样,都是类的内部实现,属于类定义的一部分。普通的成员函数一般都隐含了一个this指针,this指针指向类的对象本身,因为普通成员函数总是具体的属于某个类的具体对象的。通常情况下,this是缺省的。如函数fn()实际上是this->fn()。但是与普通函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有this指针。从这个意义上讲,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。下面举个静态成员函数的例子。
1 #include<iostream> 2 using namespace std; 3 4 class Myclass 5 { 6 private: 7 int a , b , c; 8 static int sum; //声明静态数据成员 9 public: 10 Myclass(int a , int b , int c); 11 static void GetSum(); //声明静态成员函数 12 }; 13 14 int Myclass::sum = 0; //定义并初始化静态数据成员 15 16 Myclass::Myclass(int a , int b , int c) 17 { 18 this->a = a; 19 this->b = b; 20 this->c = c; 21 sum += a+b+c; //非静态成员函数可以访问静态数据成员 22 } 23 void Myclass::GetSum() //静态成员函数的实现 24 { 25 //cout<<a<<endl; //错误代码,a是非静态数据成员 26 cout<<"sum="<<sum<<endl; 27 } 28 29 int main(void) 30 { 31 Myclass M(1 , 2 , 3); 32 M.GetSum(); 33 Myclass N(4 , 5 , 6); 34 N.GetSum(); 35 Myclass::GetSum(); 36 return 0; 37 }
关于静态成员函数,可以总结为以下几点:
http://www.cnblogs.com/10jschen/archive/2012/09/22/2698139.html
C++中static 的使用方式,以及与c中的static的区别,布布扣,bubuko.com
C++中static 的使用方式,以及与c中的static的区别
标签:style class blog code java http
原文地址:http://www.cnblogs.com/xaf-dfg/p/3784518.html