c++类——静态成员

本文最后更新于:1 年前

(一)概念:

类成员冠以static声明时,称为静态成员。静态成员用于解决类内数据共享的问题,既能够避免使用全局变量,又能够让同类的多个对象数据共享。

如果使用全局变量对封装的类来说并不安全,因为其他的类外函数能共享、修改全局变量,同时容易发生名字的冲突问题。

静态成员包括静态数据成员和静态成员函数。

下面分别介绍。

(二)静态数据成员:

1. 概念:

c++类中声明数据成员时, 加上static关键字声明的成员成为静态数据成员。

形式:类内:static 数据类型 变量名; 声明

类外:数据类型 类名::变量名=值; / 数据类型 类名::变量名; 定义和初始化

2. 特点:

  1. 类中的静态数据成员遵守public、protected、private规则,但是只能在类中进行声明不允许在类中进行定义和初始化(为了避免产生多个对象时多次定义初始化导致值的改变,导致数据变化。在类外一经定义必须初始化。

  2. 被类的所有对象共享,只有一份内存,保存在静态存储空间中,其生命周期和整个程序相同。独立于所有对象——即使没有对象也存在,能够被访问、赋值。本质上,静态数据成员是全局变量。

  3. 可以通过对象访问静态数据成员,也可以通过类名::静态数据成员的方法去访问。

  4. 静态数据成员可以作为成员函数的默认参数值,其类型可以是所属类的类型(普通数据成员均不可)。

  5. 静态数据成员在常成员函数中可以修改。(因为this指针指向对象const但静态数据成员不是对象的)

  6. sizeof运算符计算对象所占用的存储空间时,不会将静态成员变量计算在内。类大小=非静态成员数据的类型大小之和。

3. 代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#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.特点:

  1. 静态成员函数不属于某一对象,因此静态成员函数没有this指针(与成员函数的根本区别),其本质是一个全局函数。

  2. 静态成员函数只能够访问静态成员变量,但可以直接引用本类中的静态数据成员,因无this指针,不能够默认访问一个对象中的非静态成员。

  3. 静态成员函数的实现可以在类体内,也可以在类体外。

  4. 静态成员函数的调用可以通过类,也可以通过对象,且无需对象就可以调用静态成员函数

  5. (附):静态成员函数不是绝对不能引用非静态成员,只是不能进行默认访问,因为不知道要找哪个对象,如果一定要引用,需要加对象名和成员运算符“.”。(不建议使用)

3.代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#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;
}

c++类——静态成员
https://github.com/xiaohei07/xiaohei07.github.io/2023/03/17/c++类——静态成员/
作者
07xiaohei
发布于
2023年3月17日
许可协议