目录
由关键字static修饰类中成员,成为类的静态成员。类的静态成员为其所有对象共享,不管有多少对象,静态成员只有一份存于公用内存中。静态数据成员被当做该类类型的全局对象。我们不能把静态成员的初始化放置在类的定义中,但是可以在类的外部通过使用范围解析运算符 :: 来重新声明静态变量从而对它进行初始化。
在类的设计中,用关键字static修饰的数据成员为静态数据成员。有该类型实例化的所有对象,共享系统为静态成员分配一个存储空间。而这个存储空间是程序执行main函数之前分配的,在实例化对象不再为静态成员分配空间(静态成员数据不再对象空间中)
1、设计静态数据成员的目的是信息共享,只会被初始化一次,于实例无关
示例:
- class Circle {
- private:
- static double pi;
- double rid;
- public:
- Circle(double r=0.0):rid(r){}
- ~Circle(){}
- double area()const
- {
- return pi * rid * rid;
- }
- };
- double Circle:: pi=3.14;
- int main()
- {
- cout << sizeof(Circle) << endl;
- Circle cir(12.23);
- size_t sz = sizeof(cir);
- cout << sz << endl;
- return 0;
- }
也就是说 static 并不占用Cricle的内存空间(栈区),他在全局数据区分配内存
注意:
与全局变量相比,使用静态数据成员有两个优势:
2、静态数据是该类所有对象所共有的,可以提供同一类型的所有对象之间,信息共享或信息交换的一种方式
静态数据成员属于整个类型,使用时可以用以下格式:
类名::静态数据成员名或者 对象.静态数据成员名(前提是可以访问符为public)
示例:
- #include
-
- using namespace std;
-
- class Box
- {
- public:
- static int objectCount;
- // 构造函数定义
- Box(double l=2.0, double b=2.0, double h=2.0)
- {
- cout <<"Constructor called." << endl;
- length = l;
- breadth = b;
- height = h;
- // 每次创建对象时增加 1
- objectCount++;
- }
- double Volume()
- {
- return length * breadth * height;
- }
- private:
- double length; // 长度
- double breadth; // 宽度
- double height; // 高度
- };
-
- // 初始化类 Box 的静态成员
- int Box::objectCount = 0;
-
- int main(void)
- {
- Box Box1(3.3, 1.2, 1.5); // 声明 box1
- Box Box2(8.5, 6.0, 2.0); // 声明 box2
-
- // 输出对象的总数
- cout << "Total objects: " << Box::objectCount << endl;
-
- return 0;
- }
输出结果:
- Constructor called.
- Constructor called.
- Total objects: 2
3、在类的成员函数中使用静态数据成员,静态数据成员没有this指针,this指针指向类的对象本身,而static静态成员函数不依赖对象调用,它不与任何的对象相联系,所以当然不需要this指针。
4、静态属性的类型是int,short,char等整型,并且是const,可以在类中直接初始化

注意:
静态成员函数没有this指针,因此在静态成员函数显式的使用this指针都将会导致编译时刻错误,试图访问隐式使用this指针所指向的非静态数据成员也会导致编译时刻错误
静态成员函数与普通成员函数的区别:
- 静态成员函数没有 this 指针,只能访问静态成员(包括静态成员变量和静态成员函数)。
- 普通成员函数有 this 指针,可以访问类中的任意成员;而静态成员函数没有 this 指针。
示例:
- #include
-
- using namespace std;
-
- class Box
- {
- public:
- static int objectCount;
- // 构造函数定义
- Box(double l=2.0, double b=2.0, double h=2.0)
- {
- cout <<"Constructor called." << endl;
- length = l;
- breadth = b;
- height = h;
- // 每次创建对象时增加 1
- objectCount++;
- }
- double Volume()
- {
- return length * breadth * height;
- }
- static int getCount()
- {
- return objectCount;
- }
- private:
- double length; // 长度
- double breadth; // 宽度
- double height; // 高度
- };
-
- // 初始化类 Box 的静态成员
- int Box::objectCount = 0;
-
- int main(void)
- {
-
- // 在创建对象之前输出对象的总数
- cout << "Inital Stage Count: " << Box::getCount() << endl;
-
- Box Box1(3.3, 1.2, 1.5); // 声明 box1
- Box Box2(8.5, 6.0, 2.0); // 声明 box2
-
- // 在创建对象之后输出对象的总数
- cout << "Final Stage Count: " << Box::getCount() << endl;
-
- return 0;
- }
编译结果:
- Inital Stage Count: 0
- Constructor called.
- Constructor called.
- Final Stage Count: 2
不能使用if,循环,公式,求n的累加
- //使用静态数据成员,调用n次构造函数,产生n次累加
- class ADD
- {
- private:
- static int a;
- static int b;
- public:
- ADD() {
- a += b;
- b++;
- };
- int Getnumber()
- {
- return a;
- }
-
- };
- int ADD:: a=0;
- int ADD::b=1;
- //三目运算符求解
- int ADD1(int n)
- {
- return n == 1 ? 1 : ADD1(n - 1) + n;
- }
- int main()
- {
- ADD* x = new ADD[100];
- cout << x->Getnumber() << endl;
- cout << ADD1(100) << endl;
- return 0;
- }
为什么static成员函数不能是const?

静态成员函数是属于某个类的,而不是某个对象。所以在类被定义的时候,在对象被定义之前就已经存在了,所以显然也可以看出他不是某个对象,但是const是用来修饰对象的,使对象保持不变,里面的数据成员保持不变,那么对于不是对象的static函数,就不可以用const修饰了。函数中的const其实就是用来修饰this指针的,意味this指向的内容不可变,static成员函数没有this,就不能使用const