如有兴趣了解更多请关注我的个人博客https://07xiaohei.com/
(一)概念:
类成员冠以static声明时,称为静态成员。静态成员用于解决类内数据共享的问题,既能够避免使用全局变量,又能够让同类的多个对象数据共享。
如果使用全局变量对封装的类来说并不安全,因为其他的类外函数能共享、修改全局变量,同时容易发生名字的冲突问题。
静态成员包括静态数据成员和静态成员函数。
下面分别介绍。
(二)静态数据成员:
1. 概念:
c++类中声明数据成员时, 加上static关键字声明的成员成为静态数据成员。
形式:类内:static 数据类型 变量名; 声明
类外:数据类型 类名::变量名=值; / 数据类型 类名::变量名; 定义和初始化
2. 特点:
- 类中的静态数据成员遵守public、protected、private规则,但是只能在类中进行声明,不允许在类中进行定义和初始化(为了避免产生多个对象时多次定义初始化导致值的改变,导致数据变化。在类外一经定义必须初始化。
- 被类的所有对象共享,只有一份内存,保存在静态存储空间中,其生命周期和整个程序相同。独立于所有对象——即使没有对象也存在,能够被访问、赋值。本质上,静态数据成员是全局变量。
- 可以通过对象访问静态数据成员,也可以通过类名::静态数据成员的方法去访问。
- 静态数据成员可以作为成员函数的默认参数值,其类型可以是所属类的类型(普通数据成员均不可)。
- 静态数据成员在常成员函数中可以修改。(因为this指针指向对象const但静态数据成员不是对象的)
- sizeof运算符计算对象所占用的存储空间时,不会将静态成员变量计算在内。类大小=非静态成员数据的类型大小之和。
3. 代码实现:
#include<iostream>
using namespace std;
class Point
{
private:
double x, y;
public:
static int pointcounter;//声明
Point()
{
x = 0;
y = 0;
pointcounter++;//可以使用,不是定义初始化
}
Point(double x, double y)
{
this->x = x;
this->y = y;
pointcounter++;//同上
}
void move(double x, double y)
{
this->x = x;
this->y = y;
}
double getX()
{
return x;
}
double getY()
{
return y;
}
~Point()
{
pointcounter--;//仍旧存在,不会销毁,可以访问。
}
};
int Point::pointcounter = 0;//在此处定义和初始化
int main()
{
cout << "现存点数:" << Point::pointcounter << endl;//可以观察其变化情况是否独立于对象。
Point* p1 = new Point(1, 1);
Point* p2 = new Point(2, 2);
Point* p3 = new Point(3, 3);
cout << "现存点数:" << Point::pointcounter << endl;
delete p1;
delete p2;
cout << "现存点数:" << Point::pointcounter << endl;
delete p3;
cout << "现存点数:" << Point::pointcounter << endl;
return 0;
}
(三)静态成员函数:
1. 概念:
静态成员函数是指用static修饰的成员函数。
静态成员函数的作用不是为了对象之间的沟通,而是为了能处理静态数据成员。
形式:static 返回类型 函数名( 参数表) { 函数体 }
2.特点:
- 静态成员函数不属于某一对象,因此静态成员函数没有this指针(与成员函数的根本区别),其本质是一个全局函数。
- 静态成员函数只能够访问静态成员变量,但可以直接引用本类中的静态数据成员,因无this指针,不能够默认访问一个对象中的非静态成员。
- 静态成员函数的实现可以在类体内,也可以在类体外。
- 静态成员函数的调用可以通过类,也可以通过对象,且无需对象就可以调用静态成员函数。
- (附):静态成员函数不是绝对不能引用非静态成员,只是不能进行默认访问,因为不知道要找哪个对象,如果一定要引用,需要加对象名和成员运算符“.”。(不建议使用)
3.代码实现:
#include<iostream>
using namespace std;
class Point
{
private:
double x, y;
public:
static int pointcounter;
static void addpointconuter() //类内声明
{
pointcounter++;//允许对静态数据成员进行操作
//x++; //不允许直接调用默认成员。
return;
}//静态成员函数
static void delpointconuter();
Point()
{
x = 0;
y = 0;
pointcounter++;
}
Point(double x, double y)
{
this->x = x;
this->y = y;
pointcounter++;
}
void move(double x, double y)
{
this->x = x;
this->y = y;
}
double getX()
{
return x;
}
double getY()
{
return y;
}
~Point()
{
pointcounter--;
}
} p;
void Point::delpointconuter() //类外声明
{
this->x = this->y = 0;//错误,根本没有this指针。
p.x = p.y = 0;
pointcounter = 0;
}
int Point::pointcounter = 0;
int main()
{
Point* p1 = new Point(1, 1);
Point* p2 = new Point(2, 2);
Point* p3 = new Point(3, 3);
cout << "现存点数:" << Point::pointcounter << endl;
Point::addpointconuter();
cout << "现存点数:" << Point::pointcounter << endl;
Point::delpointconuter();
cout << "现存点数:" << Point::pointcounter << endl;
delete p1;
delete p2;
cout << "现存点数:" << Point::pointcounter << endl;
delete p3;
cout << "现存点数:" << Point::pointcounter << endl;
return 0;
}