8. 类的静态成员

news/2025/1/2 2:09:09/

一、对象的生产期

  • 生存期:对象从诞生到结束的这段时间
  • 生存期分为静态生存期和动态生存期

1.1 静态生存期

  • 对象的生存期与程序的运行期相同则称它具有静态生存期
  • 在文件作用域中声明的对象都是具有静态生存期的
  • 若在函数内部的局部作用域中声明具有静态生存期的对象,则要使用static关键字
    • 局部作用域中静态变量的特点
      • 不会随着每次函数调用而产生一个副本,也不会随着函数返回而失效,该变量会在各次调用间共享

1.2 动态生存期

  • 非静态变量的对象都具有动态生存期
  • 在局部作用域中声明的具有动态生存期的对象,也称为局部生存期对象,它诞生于声明点,结束于声明所在的块执行完毕之时

二、类的静态成员

2.1 类静态成员的特点

  • 用关键字static声明
  • 为该类的所有对象共享,静态数据成员具有静态生存周期
  • 必须在类外定义和初始化,用 “ :: ” 来指明所属的类
    • “ :: ” 是作用域操作符

2.2 为什么需要静态数据成员?

示例:

#include <iostream>
using namespace std;// 一个点类,点的属性:坐标
class Point{
private:int x, y;
public:Point(int x = 0, int y = 0) : x(x), y(y){ } ~Point() { }int getX() { return x; }int getY() { return y; }
};

上述代码是一个点类的模板,每新创建一个点类对象都会调用一次上述函数

image-20230510093819310

每个类的实例都创建都创建一个独立的对象,每个对象都复制了类的数据或属性

每个对象管理各自得属性值

  • 假设增加一个需求:统计点的总个数。考虑添加一个计数的数据成员

  • 要求:

    • 必须在任何时候都能在每个Student对象中使用加法函数
    • 当生成一个新的Student实例的时候,必须保证,所有Student对象都实现了总人数的计数
    class Point{
    private:int x, y;int count;	// 用于记录点的个数
    public:Point(int x = 0, int y = 0) : x(x), y(y){ } ~Point() { }int getX() { return x; }int getY() { return y; }void addCount() { count++; }void showCount() {count << " Object count = " << count << endl;}
    };
    
    image-20220606213201865

    上述代码存在的问题:

    • 每次新定义一个点类,都要手动的修改count值,定义第1个则count改为1,定义第2个则count改为2,同时要将第1个对象的count值改为2,定义第3个则count改为3,同时要将第1个和第2个对象的count值改为3……

    解决办法:指定count为一个静态数据成员

    image-20220606214017145
    • 局部静态变量的生存期域程序的运行时间相同
    • count仍然是局部变量,可以看成是所有Point对象共享的一般变量
    class Point{
    private:int x, y;static int count;	// 静态数据成员声明,用于记录点的个数
    public:Point(int x = 0, int y = 0) : x(x), y(y){ count++; } // 每次创建对象时都会自动调用,自动将对象个数加1~Point() { count--; }	// 每次撤销对象的时候自动调用,对象个数自动减1int getX() { return x; }int getY() { return y; }void showCount() {count << " Object count = " << count << endl;}
    };// 静态数据成员在类外定义和初始化,使用类名限定
    int Point::count = 0;int main() {Point a(4, 5);	// 定义对象a,其构造函数会使count加1cout << "Point A: " << a.getX() << ", " << a.getY();a.showCount();	// 输出对象个数Point b;	// 定义对象b,其构造函数会使count加1cout << "Point B: " << b.getX() << ", " << b.getY();b.showCount();	// 输出对象个数return 0;
    }
    
image-20230510101157944

三、静态成员函数

  • 类外代码可以使用类名和作用域操作符来调用静态成员函数
  • 静态成员函数只能引用属于该类的静态数据成员或静态成员函数

示例:

class Point{
private:int x, y;static int count;	// 静态数据成员声明,用于记录点的个数
public:Point(int x = 0, int y = 0) : x(x), y(y){ count++; }   // 每次创建对象时都会自动调用,自动将对象个数加1~Point() { count--; }								// 每次撤销对象的时候自动调用,对象个数自动减1int getX() { return x; }int getY() { return y; }static void showCount() {count << " Object count = " << count << endl;}
};// 静态数据成员在类外定义和初始化,使用类名限定
int Point::count = 0;int main() {Point a(4, 5);	// 定义对象a,其构造函数会使count加1cout << "Point A: " << a.getX() << ", " << a.getY();Point::showCount();	// 输出对象个数Point b;	// 定义对象b,其构造函数会使count加1cout << "Point B: " << b.getX() << ", " << b.getY();Point::showCount();	// 输出对象个数return 0;
}

http://www.ppmy.cn/news/65936.html

相关文章

opencv_c++学习(六)

一、视频加载与摄像头调用 视频、摄像头加载 VideoCapture(filename, CAP_ANY)对以上实例解释如下&#xff1a; 若读取的为本地视频&#xff0c;则filename为视频名称&#xff0c;若读取的是摄像头数据&#xff0c;则为int类型的摄像头id。 视频属性的获取 视频属性可以通过…

OpenGL超级宝典第七章学习笔记:顶点处理与绘图命令

前言 本篇在讲什么 OpenGL蓝宝书第七章学习笔记 本篇适合什么 适合初学OpenGL的小白 本篇需要什么 对C语法有简单认知 对OpenGL有简单认知 最好是有OpenGL超级宝典蓝宝书 依赖Visual Studio编辑器 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&…

vue+elementui+nodejs校园高校餐厅点餐及订餐菜品推荐评价系统6927k

传统的销售模式&#xff0c;在实体店的紧跟式的销售模式&#xff0c;会给消费者一种不自由&#xff0c;被监视的感觉。餐厅点餐及推荐系统&#xff0c;紧跟数据时代的步伐&#xff0c;使用nodejs开发语言&#xff0c;配备MySQL数据库。扎根于实际问题所开发出来的一套系统。这个…

一百一十、Hive时间转换——from_unixtime踩坑(不要用from_unixtime,而是用from_utc_timestamp)

1.详情 从kettle转换任务得到时间戳为13位&#xff0c;1683701579457。想看看这个时间戳与createTime字段的关系&#xff0c;于是一开始使用了from_unixtime&#xff0c;结果踩坑了 2.运行问题&#xff08;晚8个小时&#xff09; hive> select from_unixtime(cast(1683701…

基于 TiDB + Flink 实现的滑动窗口实时累计指标算法

作者&#xff1a;李文杰 前言 在不少的支付分析场景里&#xff0c;大部分累计值指标可以通过 Tn 的方式计算得到 。随着行业大环境由增量市场转为存量市场&#xff0c;产品的运营要求更加精细化、更快速反应&#xff0c;这对各项数据指标的实时性要求已经越来越高。产品如果能…

c# The handshake failed due to an unexpected packet format 异常处理

异常信息&#xff1a; System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: The handshake failed due to an unexpected packet format.at System.Net.Security.SslState.StartReadFra…

Java 中的基本数据类型有哪些?

Java 中的基本数据类型共有八种&#xff0c;分为两类&#xff1a;原始类型和引用类型。 原始类型&#xff08;Primitive Types&#xff09; 原始类型是 Java 语言中最基本的数据类型&#xff0c;它们是直接存储在计算机内存中的。Java 中的原始类型有 8 种&#xff0c;分别是&…

入门级的家用洗地机怎么样?入门级洗地机推荐

洗地机的功能有很多&#xff0c;比如除菌、洗地机清洁地面的确是一把好手。但是&#xff01;清洁完之后还要手动清洗洗地机&#xff0c;是一件麻烦事啊&#xff01;现在市面上大部分洗地机都有自清洁这个功能&#xff0c;但是很多洗地机的自清洁并不算真正的自清洁&#xff0c;…