翁恺老师说static

来源:互联网 发布:java 在线视频播放 编辑:程序博客网 时间:2024/04/27 21:14

我们在C的时候就学到过static,static在C就是一个很复杂的东西,因为static关键字被赋予了完全不同的职责,出现在不同地方代表了完全不同的含义,对C来说static就是两义的,它出现在不同地方代表的是完全不同的含义。
第一层含义代表其存储是持久存储的
第二层含义代表其访问性是受局限的
这是两个完全不同的事情,一个是说你在哪里,另一个是说谁能看到你
在c++中static的含义变得更复杂,c++中有成员变量和成员函数。
在C中一个全局变量是static的这个全局变量就只在当前的.c文件中有效。一个本地变量是static的这个本地变量就具有持久存储了。
实际上static的本地变量就是全局变量,其存储位置和全局变量一致。一个static的函数只能在当前.c文件被访问。
c++中static的普通函数和全局变量已经过时,static的本地变量是持久存储的,static的成员变量在所有对象之间共享和static的成员函数在所有对象之间共享且只能访问静态的成员变量。

static free functions - deprecated
static global variables - deprecated
static local variables - persistent storage
static member variables - shared by all instances
static member function - shared by all instances,can only access static member varibles

一个.c文件中的全局变量在另一个.c文件中使用时需加上extern关键字。一个.c文件中的static的全局变量在另一个.c文件不能通过extern关键字使用。
c++中static的本地对象,只在第一次进函数时调用构造函数,其内存空间在编译时分配。

class X{X(int,int);~X();...}void f(){static X my_x(10,20);...}

全局对象的空间在全局数据区,编译链接时分配空间,全局变量的构造的执行在main函数之前,所以main可能不是程序第一个被调用的函数。main结束或者调用exit结束程序时执行析构函数。

extern int i;

上述这句话是一句声明,在声明这句话的.cpp文件中并没有i的位置,这句话只是告诉编译器有一个i的东西存在,但不知道具体位置,将来链接器会去找。

class A{public:    A();    void print(){cout << i << endl;}    void set(int ii){ i = ii; }private:    static int i;};int main(){    A a,b;    a.set(10);    b.print();    return 0;}

上述代码编译通不过,因为static int i只是声明不是定义,必须在本.cpp或者其他cpp文件将i定义出来即int A::i;
静态的成员变量必须将i定义出来才可以使用。
两段错误代码:

class A{public:    A:i(0)();//error,静态成员变量只能在其定义的地方初始化    void print(){cout << i << endl;}    void set(int ii){ i = ii; }private:    static int i;};int A::i=0;//right,这里是i的定义int main(){    A a,b;    a.set(10);    b.print();    return 0;}
class A{public:    A();    void print(){cout << i << endl;}    void set(int ii){ i = ii; }private:    static int i;};static int A::i;//error,从C语言的角度看这个i只能在当前.cpp文件中被访问,这和类静态成员的访问属性相违背,因为静态成员是可能在外部被访问的,不能加static,会导致编译错误。int main(){    A a,b;    a.set(10);    b.print();    return 0;}

静态的成员函数只能访问静态的成员变量,因为静态的成员函数可以通过类名直接调用可与对象无关,所以静态成员变量没有隐藏的this指针,不能访问类中的非静态成员变量。