回顾:
(1)static关键字指明变量的“静态”属性——static修饰的局部变量和全局变量存储在程序静态区(静态变量,只能被初始化一次)
(2)static关键字同时具有“作用域限定符”
①static修饰的全局变量作用域只是声明的文件中
②static修饰的函数作用域只是声明的文件中
新的内容---------成员变量之前加入修饰静态-------静态成员变量与成员变量的区别??????
成员变量---对象里的变量
(1)变量反映一个对象的状态,每个对象都有自己的一套成员变量
(2)每个对象的成员变量是专属的,所以成员变量不能共享
(3)public成员变量可以通过对象名访问
1. 成员变量的回顾
(1)通过对象名能够访问public成员变量
(2)每个对象的成员变量都是专属的----------面向对象设计中--成员变量是私有的,至少不是私有的
(3)成员变量不能在对象之间共享
2、新的需求
-
统计在程序运行期间某个类的对象数目
-
保证程序的安全性(不能使用全局变量)----全部变量你几乎可以在任意地方修改它,如果程序很大, 几万行, 几十个文件, 就不知道在哪修改了这个变量?也不知道修改了这个变量对后面使用有何影响?---一句话公共财产不安全
-
随时可以获取当前对象的数目
实验:
1 #include<stdio.h> 2 /* 3 不使用全局变量,获取某个类的对象数目 ???? 4 */ 5 class Test 6 { 7 private: 8 int mCount; //定义变量 9 10 public: 11 Test() : mCount(0) 12 { 13 mCount++; //创建对象,变量++-------对象增加一个 14 } 15 ~Test() 16 { 17 mCount--; //析构对象,变量-- 18 } 19 20 int getCount() 21 { 22 return mCount; 23 } 24 }; 25 26 Test gTest; //全局对象 27 28 int main() 29 { 30 Test t1; //局部对象 31 Test t2; 32 33 printf("count=%d\n", gTest.getCount()); //1 34 printf("count=%d\n", t1.getCount()); //1 35 printf("count=%d\n", t2.getCount()); //1 36 37 38 //期望打印3个 3个Test对象 39 //因为3对象都有一套成员变量mCount,mCount在构造是初始化为0,构造函数++,所以打印三个1 40 41 return 0; 42 }
那怎么实现呢?????
3. 静态成员变量
(1)C++中的静态成员变量
①静态成员变量属于整个类所有
②静态成员变量的生命期不依赖于任何对象-------和全局变量一样,程序的运行周期
③可以通过对象名,也可以通过类名直接访问公有静态成员变量
④所有对象共享类的静态成员变量
静态成员变量---说明静态成员变量是有访问等级的,可以public、也可以private
(2)静态成员变量的特性
①在定义时直接通过static关键字修饰
②静态成员变量在程序内部位于全局数据区,所以需要类外为其单独分配空间。----------本质和全局变量、静态全局变量一致,存储在同一个地方
(因为new或栈中的对象只会为非静态成员分配空间,而不会为静态成员分配,所以必须在类外单独为其分配空间)
③为静态成员变量分配空间的语法规则:
Type ClassName::VarName = value; //要像定义全局变量一样放在函数外
1 #include<stdio.h> 2 3 //以下是使用静态成员变量,通过类名访问 4 //静态成员变量需要在类的外部单独分配(全局数据区) 5 6 class Test 7 { 8 private: 9 static int cCount; //静态成员变量------用static修饰普通成员变量 10 11 public: 12 Test() 13 { 14 cCount++; 15 } 16 ~Test() 17 { 18 cCount--; 19 } 20 21 int getCount() 22 { 23 return cCount; 24 } 25 }; 26 27 //使用前必须在类外给静态成员变量分配空间-------静态成员变量,不隶属于某个对象,所以要单独定义它,是的编译器知道静态成员变量需要在全局数据区分配空间 28 int Test::cCount = 0; //表明要在全局区,而且只能在全局区分配空间,属于Test类,并初始化为0 29 30 Test gTest; //全局对象 31 32 int main() 33 { 34 35 Test t1; //局部对象 cCount增加1 36 Test t2; //cCount增加1 37 38 printf("sizeof(Test) = %d, sizeof(t1) = %d\n", 39 40 sizeof(Test), sizeof(t1)); //等于1,表示cCount是在全局区分配空间, 41 42 //该变量不属于某个对象本身的。 43 44 45 printf("count=%d\n", gTest.getCount()); //3 46 printf("count=%d\n", t1.getCount()); //3 47 printf("count=%d\n", t2.getCount()); //3 48 49 Test* pt = new Test(); //指针指向Test对象 50 printf("count=%d\n", pt->getCount()); //4--------动态堆空间生成Test对象,New触发构造函数调用, 51 delete pt; //delete count-- =3 52 53 printf("count=%d\n", gTest.getCount()); //3 54 55 //printf("count = %d\n", Test::cCount);//错误,通过类名只能访问公有的static成员变量 56 57 return 0; 58 }
4. 小结
(1)类中可以通过static关键字定义静态成员变量
(2)静态成员变量隶属于类所有
(3)每一个对象都可以访问静态成员变量(可以通过类名和对象访问)
(4)静态成员变量在全局数据区分配空间
(5)静态成员变量的生命期为程序运行期