深入探索C++类的静态成员变量
基础和特点
1. 静态数据成员的声明:要声明一个静态数据成员,只需在数据成员的前面加上 static关键字即可。比如 class A{ static int a; };
,其中a就是一个静态数据成员。
2. 静态数据成员属于整个类,而不属于某个对象,因此其具有以下特点。
2.1 静态数据成员被类的所有对象共享,每个类对象都只有静态数据成员一份共同的副本,因此该类及其所有对象使用的都是同一个静态
数据成员。若静态数据成员的值发生了改变,则对所有该类的对象而言,该值都被改变了。比如 class A{public:static int b;};int A::a=3;A ma,mb;
,若 ma.b=2;,则 ma.b; 的值也会改变为2。静态变量 b 属于整个类,被类的所有对象共享,因此 ma.b 和 mb.b 都是指相同的静态变量 b,使用 ma.b 改变 b 的值,会使 ma.b 的值也发生改变。int A::a 是对静态数据成员的定义。
2.2 即使不创建任何类的对象,但是只要定义了静态数据成员,程序就可以使用静态数据成员,因为静态数据成员属于类而不是对象。比如 class A{ public: static int a; }; intA::a=3;
,则 A::a=4; 对静态数据成员 a 重新赋值是正确的。其中 int A::a=3; 是对静态数据成员的定义,A:a 是使用类名引用静态数据成员的方法。
2.3 创建对象只会为对象的非静态数据成员分配内存,而不会为静态数据成员分配内存,因此在类中只是对静态数据成员的声明而非定义,若未定义静态数据成员就直接使用,将产生错误。比如 class A{ public:static int a; int b;}; A ma;
,则 ma.a=3; 是错误的,因为创建 ma 后只会为非静态数据成员 b 分配内存,而不会为静态数据成员 a 分配内存。
2.4 静态数据成员的类型可以是静态数据成员所属的类类型,而非静态数据成员则不可以。比如 class A{public:static A a; A b;};
,其中static A a;是正确的,而 A b; 则是错误的。
2.5 静态数据成员可以作为默认实参,而非静态数据成员则不可以,因为非静态数据成员的值在被使用之前必须先绑定到该类的某个对象(或对象的指针)上,因此非静态数据成员无法提供对象,从而得到该成员的值。所以默认实参不能是类的非静态数据成员。比如 class A{public:static int a;int b; void f(int i = a) {} void g(int i=b) {}};
,其中函数f是正确的,函数g是错误的,因为使用了非静态数据成员b作为默认实参。
3. 静态数据成员可以是public(公有的)、private (私有的)、protected (受保护的)。
4. 静态数据成员也可以是类类型对象、数组、const常量、引用等。
5. 在成员函数中可以像使用普通数据成员一样使用静态数据成员,只不过要注意静态数据成员属于整个类这个特性。
//静态成员变量:在一个类中,在一个成员变量前面加static,在类中声明,类外定义
class Person
{
public:
static int m;//类内声明
};
int Person::m = 10; //类外初始化
void test()
{
Person p1;
p1.m = 20;
cout << p1.m << endl; //通过对象访问
cout << Person::m << endl; //通过类名访问
}
int main()
{
test();
return 0;
}
该文章会更新,欢迎大家批评指正。
推荐一个零声学院免费公开课程,个人觉得老师讲得不错,
分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习:
服务器课程:C++服务器