C和C++的static

来源:互联网 发布:微信扫淘宝二维码 编辑:程序博客网 时间:2024/06/13 04:50

一、C语言static属性

1、所有没有加static的全局变量和函数都具有全局的可见性,添加static后,改变量和函数会对其他.c文件隐藏,只能在当前文件中引用

2、static的第二个作用是保持变量内容的持久。static变量中的记忆功能和全局生存期,换句话说,static变量只初始化一次。存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。共有两种变量存储在静态存储区:全局变量和static变量,只不过和全局变量比起来,static可以控制变量的可见范围,说到底static还是用来隐藏的

注意:如果作为static局部变量在函数内定义,它的生存期为整个源程序,但是其作用域仍与自动变量相同,只能在定义该变量的函数内使用该变量。退出该函数后, 尽管该变量还继续存在,但不能使用它

总结前两条:

  • static修饰局部变量:改变了生存周期和只能被初始化一次的性质
  • Static 修饰全局变量:限制了他的使用范围

3、在静态数据区,内存中所有的字节默认值都是0x00。所以static的第三个作用是默认初始化为0(static变量),全局变量也是一样


二、C++的static属性

在类中声明static变量或者函数时,初始化时使用作用域运算符来标明它所属类,因此,静态数据成员是类的成员,而不是对象的成员,这样就出现以下作用。

(1) 类的静态成员函数是属于整个类而非类的对象,所以它没有this指针,这就导致 了它仅能访问类的静态数据和静态成员函数

(2) 不能将静态成员函数定义为虚函数, 出现在类体外的函数定义不能指定关键字static

(3)由于静态成员声明于类中,操作于其外,所以对其取地址操作,变量地址是指向其数据类型的指针 ,函数地址类型是一个“nonmember函数指针”。

(4)static并没有增加程序的时空开销,相反她还缩短了子类对父类静态成员的访问 时间,节省了子类的内存空间。 

  •  对于非静态数据成员,每个类对象都有自己的拷贝。
  • 而静态数据成员被当作是类的成员。无论这个类的对象被定义了多少个,静态数据成员在程序中也只有一份拷贝,由该类型的所有对象共享访问。也就是说,静态数据成员是该类的所有对象所共有的。对该类的多个对象来说,静态数据成员只分配一次内存,供所有对象共用。所以,静态数据成员的值对每个对象都是一样的,它的值可以更新

(5)静态数据成员是静态存储的,所以必须对它进行初始化。 (程序员手动初始化,否则编译时一般不会报错,但是在Link时会报错误)   

静态成员初始化与一般数据成员初始化不同:

初始化在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆;

初始化时不加该成员的访问权限控制符private,public等;   

初始化时使用作用域运算符来标明它所属类;

• 静态数据成员初始化的格式为:

<数据类型><类名>::<静态数据成员名>=<值> 

• 类的静态数据成员有两种访问形式:

<类对象名>.<静态数据成员名> 或 <类类型名>::<静态数据成员名>

(6)静态数据成员和普通数据成员一样遵从public,protected,private访问规则

(7)静态数据成员与全局变量的比较

  • 1. 静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性; 
  • 2. 可以实现信息隐藏。静态数据成员可以是private成员,而全局变量不能
(8)静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;

非静态成员函数可以任意地访问静态成员函数和静态数据成员;

静态成员函数不能访问非静态成员函数和非静态数据成员

调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以直接使用如下格式:

<类名>::<静态成员函数名>(<参数表>)

三、示例代码

#pragma once#include <string>class TestStatic{public:TestStatic(){}TestStatic(int _a, int _b, int _c) : a(_a),b(_b),c(_c) {}virtual ~TestStatic();static int GetAge(); // 声明静态成员函数static int temp;private:int a, b, c;static unsigned int age; //静态变量};

#include "TestStatic.h"unsigned int TestStatic::age = 22; //静态变量初始化int TestStatic::temp = 2;int TestStatic::GetAge() //静态函数{return age++;}TestStatic::~TestStatic(){    //dtor}

#include <iostream>#include "TestStatic.h"using namespace std;int main(){TestStatic teststatic;    //访问静态成员方法    teststatic.temp;    //或者    TestStatic::temp;    //调用静态函数    teststatic.GetAge();    //或者    TestStatic::GetAge();return 0;}


0 0