static关键字

http://hi.baidu.com/helfen/blog/item/d6d208dba1d1146ed0164e29.html

// C++   static   类的静态成员函数

#include <iostream.h>

class ok
{
int a;
static int s;//声明静态数据成员
public:
ok(int a);
static void show();//声明静态成员函数
};

int ok::s=0;//定义并初始化静态数据成员

ok::ok(int a)
{
this->a=a;
s+=a; //非静态成员函数可以访问静态数据成员
}

void ok::show() //静态成员函数的实现
{
//cout<<a<<endl; //错误代码,a是非静态数据成员
cout<<"s="<<s<<endl;
}

void main()
{
ok cat(2);
cat.show();
ok dog(3);
dog.show();
ok::show();
}


/*------------------------------------------------------------
○静态成员之间可以相互访问,如静态成员函数访问静态数据成员和静态成员函数;
○静态成员函数没有this指针。无法访问属于类对象的非静态数据成员和非静态成员函数,
○非静态成员函数可以访问静态成员函数和静态数据成员;
○静态成员函数不能访问非静态成员函数和非静态数据成员;
○由于没有this指针的额外开销,因此静态成员函数与类的非静态函数相比速度上会有少许的增长;
○非静态成员函数总是具体的属于某个类的具体对象,this是缺省的;
○在类内部声明static成员函数的时候,必须指定static关键字。然而,在类外部定义类成员函数的时候,则一定不可以出现static关键字了!切记!

下面用一个简单的程序加以理解

    1. #include <iostream>  
    2. #include <string>  
    3. using namespace std;  
    4.   
    5. class   Test     
    6. {  
    7.     public:  
    8.         static int j;  
    9.         static void   init();//init定义为static 或非static都可以修改static成员i的值  
    10.         static int revise_i(int x);  
    11.         int  get_i();   
    12.         //由于没有this指针,static成员函数不能反问对象的非static成员,用static输出k是非法的  
    13.       
    14.     private:  
    15.         static int i;  
    16.         int k;  
    17.         const static int r = 1; //只有const static 成员在类定义时初始化  
    18.         //若将上面的i直接初始化,编译时报错  
    19. };  
    20.   
    21. //外部定义时不能再标示static  
    22. int Test::i=0; //very important:外部定义(正好一次),之后i只能通过init修改  
    23. int Test::j=5; //j为public,之后可以直接访问和修改  
    24.   
    25. void   Test::init()  
    26. {  
    27.     i=10;  
    28. }  
    29.   
    30. int   Test::get_i()  
    31. {  
    32.     return   i;  
    33. }  
    34.   
    35. int Test::revise_i(int x)  
    36. {  
    37.     i = x;  
    38.     return i;  
    39. }  
    40.   
    41. int   main()  
    42. {  
    43.     Test   obj;  
    44.     cout << obj.get_i() << endl; //通过  
    45.     obj.init(); //私有的静态成员只能通过类的静态成员函数进行修改  
    46.     cout << obj.get_i() << endl;      
    47.     cout << Test::j << endl;  
    48.     obj.j = 15;  //公有的静态成员可以直接进行修改,访问方式可以obj.j或者Test::j  
    49.       
    50.     Test::revise_i(555);  
    51.     cout << "after revise_i, i = " << obj.get_i() << endl;  
    52.     cout << Test::j << endl;  
    53.     system("pause");  
    54.     return   0;  
    55. }

 

全局变量和static变量初始化时间问题

全局变量和STATIC变量的初始化是在 main函数之前进行的,不是在编译时进行。
程序实际的开始点是在 C 库的函数里,并不是 main 函数,C 库的函数 进行全局变量和静态变量的初始化,以及其他初始化操作然后跳转到  main 函数开始, main 函数结束的时候又会回到C库的函数里,进行必要的清理工作。

全局变量和静态变量分两种,一种是带初始化的,一种是未初始化的。
可执行程序可以分为几个段,如代码段,主要放指令,数据段,存放已初始化的全局变量和静态变量,即那些初始化的值存放在该段中,该步骤是在链接是就做好了 的。还有BSS段,存放未初始化的全局变量和静态变量,这个段在文件中不占空间,当程序加载进内存后,系统给这个段分配空间,并初始化为0,所以未初始化 的全局变量和静态变量的值都是0。

二楼所说的C库函数的初始化工作不是初始化全局变量,而是初始化环境变量、还有就是main函数的入口参数。
我们写一个命令行下的c程序是可以传入参数的,如main为
int main(int argc, char **argv)
C库函数的初始化就是把我们传入的参数组织好,这样我们就可以通过argc和argv来访问我们传给main函数的参数了。
当然,C库函数的初始化操作还做一些其他的操作。

原文地址:https://www.cnblogs.com/zmlctt/p/3690967.html