静态成员分为静态数据成员和静态成员函数
1. 静态数据成员
静态数据成员被存放在内存的某一单元内,该类的所有对象都可以访问它。无论建立多少个类的对象,都只有一个静态数据的副本。
含有静态数据成员的类在创建对象时不为静态数据成员分配存储空间。
class B
{
static float x.y;
int a,b;
};
创建一个类B的对象时,编译器只分配存储两个整形数据的空间。
将静态数据成员看成是一个全局变量,将其封装在某个类中通常有两个目的:
- 限制该变量的作用范围。 例如将其放在类的私有部分声明,则它只能由该类对象的函数成员直接访问。
- 将意义相关的全局变量和相关的操作物理放在一起,可以增加程序的可读性和可维护性。
由于静态数据成员仍是类成员。当这个类的第一个对象被建立时,所有static数据被初始化,并且,以后再建立对象时,就不需再对其初始化。初始化在类体外进行。
其格式如下:
<数据类型><类名>::<静态数据成员名>=(初始值);
对上面的类A的静态成员x、y初始化的方法:
int A::x=5;
int A::y=10;
注:如果整个程序为多个文件进行分块编译,则应该将类的声明放在头文件中,然后将静态成员的初始化放在某一源文件中。
这点类似C语言中全局变量的使用,类声明中静态变量的声明相当于外部变量声明,而静态变量的初始化相当于全局变量的定义。
如果将静态变量的初始化放在头文件中被多个源文件包含,将导致变量的重复初始化。
#include<iostream>
class A
{
static int i;
public:
A(){i++;}
int list(){return i;}
};
int A::i=0; //静态数据成员的初始化
void main()
{
A a1,a2,a3;
cout<<a1.list()<<','<<a2.list()<<','<<a3.list(); //显示均为3(因为创建三个对象,三次使得静态数据成员+1)
}
Rusult:
3,3,3
2. 静态成员函数
类的成员函数可以是静态的,可以将它看成是全局函数,将其封装在某个类中的目的和静态数据成员相同。
静态数据成员函数有以下特点:
- 静态成员函数无this指针,它是同类的所有对象共享的资源,只有一个共用的副本,因此它不能直接访问非静态的数据成员,必须通过某个该类对象才能访问。
- 在静态成员函数中访问的基本上是静态数据成员或全局变量。
- 由于静态成员函数属于类独占的成员函数,因此访问静态成员函数的消息接收者不是类对象,而是类自身。在调用静态成员函数的前面,必须缀上对象名或类名,经常用类名。
- 一个类的静态成员函数与非静态成员函数不同,调用静态成员函数是无须向它传递this指针,不需要创建任何该类的对象就可以被调用。静态成员函数的使用虽然不针对某一特定对象,但在使用时系统中最好已经存在此类的对象,否则无意义。
- 静态成员函数不能使虚函数。
#include <iostream>
#include <string>
class Student{
public:
Student(char * pName = "no name")
{
cout<<"creat one student\n";
strncpy(name,pName,40);
name[39]='\0';
noOFStudent++; //静态成员:每创建一个对象,学生人数加1
cout<<noOFStudent<<endl;
}
~Student()
{
cout<<"destruct one student\n";
noOFStudents--; //没析构一个对象,学生人数减1
cout<<noOFStudents<<endl;
}
static int number() //静态成员函数
{
return noOFStudent;
}
protected:
static int noOfStudents;
char name[40];
};
int Student::noOFStudent=0; //静态数据成员在类外分配空间和初始化
void fn()
{
Student s1;
Student s2;
cout<<Student::number()<<endl; //调用静态成员函数用类名引导
}
void main()
{
Student wang;
fn();
cout<<Student::number()<<endl;
}
Result:
Creat one student //wang
1
Creat one student //s1
2
Creat one student //s2
3
3
destruct one student //s2
2
destruct one student //s1
1
1
destruct one student //wang
0