我们可以使用static关键字把类成员定义为静态的。当我们声明类的成员为静态时,这意味着无论创建多少个类的对象,静态成员都只有一个副本。
静态成员在类的所有对象都是贡献的。如果不存在其他的初始化语句,在创建第一个对象时,所有的静态数据都会被初始化为0。我们不能把静态成员的初始化放置在类的定义中,但是可以在类的外部通过使用范围解析运算符 :: 来重新声明静态变量从而对它进行初始化。
静态成员变量
/*** static.cpp ***/ #include<iostream> using namespace std; class Box { public: static int objectCount; Box(double l = 2.0,double b = 2.0,double h = 2.0) { cout << "Construct called." << endl; length = l; breadth = b; height = h; objectCount++; } double Volume() { return length*breadth*height; } private: double length; double breadth; double height; }; int Box::objectCount = 0; int main() { Box box1(3.3,1.2,1.5); Box box2(8.5,6.0,2.0); cout << "Total object: " << Box::objectCount << endl; return 0; }
运行结果:
exbot@ubuntu:~/wangqinghe/C++/20190807$ g++ static.cpp -o static
exbot@ubuntu:~/wangqinghe/C++/20190807$ ./static
Construct called.
Construct called.
Total object: 2
静态成员函数:
如果把函数成员声明为静态的,就可以把函数和类的任何特定对象独立开来。静态成员函数即使在类对象不存在的情况下也可以被调用,静态函数只要使用类名加范围解析运算符::就可以访问。
静态成员函数只能访问静态成员数据、其他静态成员函数和类外部的其他函数。
静态成员函数有一个类范围,他们不能访问类的this指针。也可以使用静态成员函数来判断类的某些对象是否被创建。
静态成员函数和普通成员函数的区别:
静态成员函数没有this指针,只能访问静态成员(包括静态成员变量和静态成员函数)
普通成员函数有this指针,可以访问类中的任意成员;而静态成员函数没有this指针。
/*** staticfun.cpp ***/ #include<iostream> using namespace std; class Box { public: static int objectCount; Box(double l = 2.0,double b = 2.0,double h = 2.0) { cout << "Construct called." << endl; length = l; breadth = b; height = h; objectCount++; } double Volume() { return length*breadth*height; } static int getCount() { return objectCount; } private: double length; double breadth; double height; }; int Box::objectCount = 0; int main() { cout << "Init stage count: " << Box::getCount() << endl; Box box1(3.3,1.2,1.5); Box box2(8.5,6.0,2.0); cout << "final stage count: " << Box::getCount() << endl; return 0; }
运行结果:
exbot@ubuntu:~/wangqinghe/C++/20190807$ g++ staticfun.cpp -o staticfun
exbot@ubuntu:~/wangqinghe/C++/20190807$ ./staticfun
Init stage count: 0
Construct called.
Construct called.
final stage count: 2
静态成员变量在类中仅仅是声明,没有定义,所以要在类的外面
定义,实际上是给静态成员变量分配内存,如果不加定义就会报错,初始化是赋一个初始值,而定义是分配内存。
利用静态成员变量来了解构造和析构函数的调用情况。
#include<iostream> using namespace std; class Cpoint { public: static int value; static int num; Cpoint(int x,int y) { xp = x; yp = y; value++; cout << "call construct " << value << endl; } ~Cpoint() { num++; cout << "call deconstruct " << num << endl; } private: int xp; int yp; }; int Cpoint::value = 0; int Cpoint::num = 0; class CRect { public: CRect(int x1,int x2):mpt1(x1,x2),mpt2(x1,x2) { cout << "call construct" << endl; } ~CRect() { cout << "call deconstruct" << endl; } private: Cpoint mpt1,mpt2; }; int main() { CRect p(10,20); cout << "hello world!" << endl; return 0; }
运行结果:
exbot@ubuntu:~/wangqinghe/C++/20190807$ g++ construct.cpp -o construct -g
exbot@ubuntu:~/wangqinghe/C++/20190807$ ./construct
call construct 1
call construct 2
call construct
hello world!
call deconstruct
call deconstruct 1
call deconstruct 2
类中特殊成员变量的初始化问题:
- 常量变量:必须通过构造函数参数列表进行初始化
- 引用变量:必须通过构造函数参数列表进行初始化
- 普通静态变量:要在类外通过“::”初始化
- 静态整型变量:可以直接在定义的时候初始化
- 静态非整型常量:不能直接在定义的时候初始化。要在类通过”::”初始化