一、前言
类是类型而不是数据对象,每个类的对象都是该类数据成员的拷贝。然而,往往我们需要让类又有对象在类范围了内共享一个数据。这个时候,就需要定义一个静态成员,来满足类的这个要求。例如:当我们定义了一个学生类的时候,我们希望有一个变量可以帮助我们记录当前学生的总人数,如果使用全局变量的话,就会破坏类的封装性,于是这个时候就可以定义静态数据成员,来记录学生的总人数。
二、静态成员的分类以及声明方式
分类:
- 静态数据成员
- 静态成员函数
声明:
类名::静态成员名
三、静态数据成员变量
class Student
{
protected:
static int num; //声明静态数据成员
public:
Student()
{
num++;
}
static void print()
{
cout << num << endl;
}
};
int Student::num = 0; //静态数据成员必须在类外部初始化,
int main()
{
Student s;
Student::print();
system("pause");
return 0;
}
静态数据成员的注意事项:
- 静态数据成员,不属于任何一个对象,它是属于类的。如果使用对象去访问静态数据成员,那么编译器只关心该对象的类型,不关心该对象是什么。
- 静态数据成员,必须要进行初始化,而且必须要在类的外部初始化(类声明指声明类的一个“尺寸”“规格”,但是不对他进行内存分配),最好是在类定义完后,接着就是初始化类的静态数据成员。初始化方式见上述的例子
- 不可以通过类名访问非静态成员变量,可以用类名或者对象名访问静态成员变量。访问方式不同(类名::静态成员变量名,对象名.静态成员变量名)
四、静态成员函数
#include<iostream>
using namespace std;
class Student
{
protected:
static int num;
int num1;
public:
Student()
{
num1 = 2;
num++;
}
static void print()
{
cout << num << endl; //可以直接访问类的内部成员
}
};
int Student::num = 0;
int main()
{
Student s;
Student::print();
system("pause");
return 0;
}
静态成员函数的注意事项:
- 静态成员函数与其他类成员函数不同一点是:它的参数中不存在默认的this指针,例如一个普通的成员函数void a(),编译器对其进行编译时,它会被转换为:void a(Student * this),而静态成员函数就是少了这个this指针
- 因为没有this指针,所以静态成员函数不可以访问非静态成员(包括函数和变量)。
- 静态成员函数可以通过类名或者对象名进行调用,但是在最好是使用类名调用,因为使用对象名调用时,它还是只看该对象是什么类型,本质还是类名调用。