C 语言中的 static
1. static 局部变量
静态局部变量属于静态存储方式, 它具有以下特点:
(1)静态局部变量在函数内定义它的生存期为整个程序生命周期, 但是其作用域仍与自动变量相同, 只能在定义该变量的函数内使用该变量. 退出该函数后, 尽管该变量还继续存在, 但不能使用它.
(2)对基本类型的静态局部变量若在声明时未赋以初值则系统自动赋予 0 值. 而对自动变量不赋初值, 则其值是不定的.
2. static 全局变量
在全局变量的说明之前再加以 static 就构成了静态的全局变量.
(1). 非静态全局变量的作用域是整个源程序, 也即在各个源文件中都是有效的.
(2). 静态全局变量则只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它.
使用静态全局变量的好处是: 因此可以避免在其它源文件中引起错误.
3. static 函数
定义一个 static 函数, 只需在函数类型前再加一个 "static" 关键字即可, 如下所示:
- static int fun(int xxx)
- {
- ......
- }
"static" 的含义是指对函数的作用域仅局限于本文件.
使用静态函数的好处是: 不同的人编写不同的函数时, 不用担心自己定义的函数, 是否会与其它文件中的函数同名, 因为同名也没有关系.
C++ 中的 static 关键字(类中的 static 关键字)
1,static 数据成员
在类内数据成员的声明前加上关键字 static, 该数据成员就是类内的静态数据成员.
- #include
- class Myclass
- {
- public:
- Myclass(int a,int b,int c);
- void GetSum();
- private:
- int a,b,c;
- static int Sum; // 声明静态数据成员
- };
- int Myclass::Sum=0; // 定义并初始化静态数据成员
- //static int Myclass::Sum = 0; // 注意加 static, 是错误的
- Myclass::Myclass(int a,int b,int c)
- {
- this->a=a;
- this->b=b;
- this->c=c;
- Sum+=a+b+c;
- }
- void Myclass::GetSum()
- {
- cout<<"Sum="<<Sum<<endl;
- }
- void main()
- {
- Myclass M(1,2,3);
- M.GetSum(); // cout 6
- Myclass N(4,5,6);
- N.GetSum(); // cout 21
- M.GetSum(); // cout 21
- }
(1). 非 static 数据成员, 每个类对象都有自己的拷贝. static 数据成员被当作是类的成员. 无论这个类的对象被定义了多少个, 静态数据成员在程序中也只有一份拷贝, 由该类型的所有对象共享访问.
(2). 静态数据成员存储在全局数据区. 静态数据成员定义时才分配空间, 在类外定义.
在上例中, 语句 int Myclass::Sum = 0; 是定义静态数据成员;
这是因为被 static 声明的类静态数据成员, 其实体远在 main()函数开始之前就已经在全局数据段中诞生了 (见《Inside The C++ Object Model》page247)! 其生命期和类对象是异步的,(静态语意说明即使没有类实体的存在, 其静态数据成员的实体也是存的) 这个时候对象的生命期还没有开始, 如果你要到类中去初始化类静态数据成员, 让静态数据成员的初始化依赖于类的实体, 保证 static 成员变量只被定义一次的好方法,
static const int <<c++ primer>>说也必须定义在类外, 但用 dev and gcc 测试, 在类内定义也是可以的!!!
(3). 静态数据成员和普通数据成员一样遵从 public, protected, private 访问规则; 除了定义, 定义不要管访问规则.
(4). 因为静态数据成员在全局数据区分配内存, 属于本类的所有对象共享, 所以, 它不属于特定的类对象, 在没有产生类对象时其作用域就可见, 即在没有产生类的实例时, 我们就可以操作它;
(5). 静态数据成员初始化与一般数据成员初始化不同. 静态数据成员初始化的格式为:
int Myclass::Sum = 0;
(6). 类的静态数据成员有两种访问形式:
- //<类对象名>.<静态数据成员名>
- M.Sum = 0
- //<类类型名>::<静态数据成员名>
- Myclass::Sum = 0
(7). 静态数据成员主要用在各个对象都有相同的某项属性的时候. 比如对于一个存款类, 每个实例的利息都是相同的. 所以, 应该把利息设为存款类的静态数据成员. 这有两个好处, 第一, 不管定义多少个存款类对象, 利息数据成员都共享分配在全局数据区的内存, 所以节省存储空间. 第二, 一旦利息需要改变时, 只要改变一次, 则所有存款类对象的利息全改变过来了;
(8). 同全局变量相比, 使用静态数据成员有两个优势:
a. 静态数据成员没有进入程序的全局名字空间, 因此不存在与程序中其它全局名字冲突的可能性;
b. 可以实现信息隐藏. 静态数据成员可以是 private 成员, 而全局变量不能;
2,static 成员函数
static 成员函数, 它为类的全部对象服务而不是为某一个类的具体对象服务. 普通的成员函数一般都隐含了一个 this 指针, 但静态成员函数由于不是与任何的对象相联系, 因此它不具有 this 指针. 从这个意义上讲, 它无法访问属于类对象的 no-static 数据成员, 也无法访问 no-static 成员函数, 它只能调用其余的静态成员函数
(1). 在类体外, 静态函数的定义前不能加关键字 static;
(2). static 成员之间可以相互访问, 包括 static 成员函数访问 static 数据成员和访问 static 成员函数;
(3). 非静态成员函数可以任意地访问静态成员函数和静态数据成员;
(4). 静态成员函数不能访问非静态成员函数和非静态数据成员, 只能访问静态的;
(5). 由于没有 this 指针的额外开销, 因此静态成员函数与类的全局函数相比速度上会有少许的增长(友元函数也没 this 指针);
(6). 调用静态成员函数, 可以用成员访问操作符 (.) 和 (->) 或直接用类名调用静态成员函数但是, 一样要遵从 public,protected,private 访问规则.
来源: http://www.bubuko.com/infodetail-2801972.html