当前位置: 首页 > news >正文

<C++学习>C++ 静态函数

类中的静态函数,就是属于“类本身”的函数,不属于某一个具体对象。

最典型的写法是:

classZlogBase{public:staticvoidInitialize(conststd::string&config_path);staticvoidShutdown();};

这两个函数前面有static,它们就是静态成员函数。


一、怎么使用

静态函数最常见的调用方式是:

ZlogBase::Initialize("log.conf");ZlogBase::Shutdown();

也就是:

类名::函数名()

因为它属于类本身,所以不需要先创建对象。


对比一下普通成员函数

普通成员函数:

classZlogBase{public:voidlogInfo(constchar*msg)const;};

这种函数必须通过对象调用:

ZlogBaselogger("tcpserver");logger.logInfo("server start");

不能直接:

ZlogBase::logInfo("server start");// 错

因为logInfo()需要依赖某个对象内部的数据,比如:

  • m_pZlogCategory
  • this

二、为什么静态函数可以直接用类名调用

因为静态函数没有this指针

普通成员函数在内部其实默认都带着一个隐藏参数:

this

表示“当前对象是谁”。

比如:

logger.logInfo("hello");

本质上像是:

logger.logInfo(&logger,"hello");

只是这个this是编译器自动传进去的。

但是静态函数没有this,所以它不能访问对象成员变量,也不依赖某个对象。
既然它不依赖对象,那就可以直接:

ZlogBase::Initialize(...)

三、静态函数里能做什么,不能做什么

能做的

可以做和“整个类”有关、但和“某个具体对象”无关的事情。

例如:

  • 全局初始化
  • 全局释放
  • 计数器
  • 工具函数
  • 工厂函数
  • 单例访问入口

不能直接做的

不能直接访问普通成员变量,比如:

classZlogBase{protected:zlog_category_t*m_pZlogCategory=nullptr;public:staticvoidInitialize(conststd::string&config_path);};

Initialize()里不能直接写:

m_pZlogCategory=...;// 错

因为m_pZlogCategory属于某个对象,
而静态函数不知道你想操作哪个对象。


四、为什么Initialize()适合做成静态函数

你现在这个例子最典型:

ZlogBase::Initialize(LOG_FILE_PATH);

因为“初始化日志系统”这件事,本质上是整个程序级别的事情,不是某一个TcpServer或某一个System对象自己的事情。

它通常做的是:

zlog_init(LOG_FILE_PATH);

这是全局初始化。

所以它很适合写成:

staticvoidInitialize(...);

这样你在main()里程序启动时就能先调用:

ZlogBase::Initialize(LOG_FILE_PATH);

后面再去创建:

  • System
  • TcpServer
  • DevInfo

这些对象。


五、为什么要“先 Initialize,再创建对象”

因为很多对象在构造时就要用日志。

比如:

classTcpServer:publicZlogBase{public:TcpServer():ZlogBase("tcpserver"){}};

ZlogBase("tcpserver")里面可能会调用:

zlog_get_category("tcpserver");

那前提就是:
zlog 系统已经先初始化好了。

所以顺序必须是:

ZlogBase::Initialize(...);// 先初始化整个日志系统TcpServer server;// 再创建具体对象

这就是为什么Initialize()设计成静态函数,并且在main()里直接调用最合理。


六、一个非常好理解的类比

比如学校系统:

classStudent{public:staticvoidSetSchoolName(conststd::string&name);voidSetStudentName(conststd::string&name);};

学校名称

这是所有学生共享的,属于“整个类”的事情,所以适合静态函数:

Student::SetSchoolName("No.1 Middle School");

学生姓名

这是某个具体学生自己的事情,所以必须通过对象:

Student s;s.SetStudentName("Tom");

ZlogBase::Initialize()就像“设置学校名字”,是全局动作。
logInfo()就像“设置学生名字”,是对象动作。


七、静态函数常见使用场景

在实际项目里,静态函数常见于这几类:

1. 全局初始化 / 释放

像你这个:

ZlogBase::Initialize(...);ZlogBase::Shutdown();

2. 计数器

classTest{public:staticintCount();};

统计一共创建了多少对象之类。


3. 工具函数

classMath{public:staticintAdd(inta,intb);};

直接:

Math::Add(1,2);

不需要先创建Math对象。


4. 单例入口

classConfig{public:staticConfig&instance();};

八、静态函数和静态成员变量经常配合使用

例如:

classZlogBase{public:staticvoidInitialize(conststd::string&path);private:staticbools_inited;};

这里:

  • Initialize()是静态函数
  • s_inited是静态变量

这两个都属于类本身,而不是某个对象。
所以非常适合做“全局只初始化一次”的逻辑。


九、你现在这个例子应该怎么理解

你截图里的:

QCoreApplicationa(argc,argv);ZlogBase::Initialize(LOG_FILE_PATH);System*pApp=newSystem();pApp->Init();

应该理解成:

第一步

程序启动,先初始化日志系统:

ZlogBase::Initialize(LOG_FILE_PATH);

第二步

再创建系统对象:

System*pApp=newSystem();

如果System继承了ZlogBase,那它在构造时就能安全使用日志功能。


十、一句话总结

静态函数用于处理“属于整个类、而不属于某个具体对象”的事情。

所以像:

  • 初始化日志系统
  • 关闭日志系统

这种全局动作,最适合写成:

ZlogBase::Initialize(...);ZlogBase::Shutdown();

而像:

  • logInfo()
  • logError()

这种依赖对象内部状态的函数,就必须通过对象调用。


如果你愿意,我下一条可以继续专门讲一下:

静态成员变量和静态成员函数的关系,以及它们在.h/.cpp里应该怎么写。

http://www.jsqmd.com/news/460923/

相关文章:

  • 在vue3中实现动态加载组件
  • 美格智能港股上市:募资11亿港元 市值88亿港元 第三季净利降50%
  • 2026年Q1吉林优秀路边石直销厂家综合评测与推荐 - 2026年企业推荐榜
  • 03 别再用 CGLIB 了!深度解析 Byte Buddy:为什么它是现代 Java 框架的首选?
  • 2026年知名的破碎磨粉机品牌推荐:破碎磨粉机公司选择指南 - 品牌宣传支持者
  • FPN网络学习
  • 2026年吉林石材厂选购指南:五大厂商深度评测与推荐 - 2026年企业推荐榜
  • 别焦虑!保姆级OpenClaw上手方案来袭!
  • GitCode gitee 上传超过10m大文件附件的方法
  • 2026年比较好的粉碎机厂家推荐:塑料粉碎机可靠供应商推荐 - 品牌宣传支持者
  • 人脸识别dlib下载与安装
  • Flutter 三方库 super_log 的鸿蒙化适配指南 - 实现极具视觉冲击力的彩色终端日志、支持动态过滤与全局异常捕获
  • 如何在Python中实现随机睡眠:从基础到进阶
  • 高效异步请求处理:Python多线程与协程实践指南
  • AI角色的“倾斜角度“处理原理
  • 【2025最新】基于SpringBoot+Vue的高校实习管理系统管理系统源码+MyBatis+MySQL
  • 2026年靠谱的螺纹通规检测机品牌推荐:螺栓通止规检测机源头工厂推荐 - 品牌宣传支持者
  • 2026年3月山东伸缩缝实力企业盘点与深度解析 - 2026年企业推荐榜
  • 用Claude写代码,选什么语言最快?实测13种编程语言后的意外发现
  • 从代码生成到数字生命:构建演化的模块库
  • Java全栈开发面试实录:从基础到实战的全面解析
  • 未来之窗昭和仙君(八十四)系统_拍照功能说明书—东方仙盟练气
  • 2026年口碑好的异型珍珠棉板材公司推荐:EPE珍珠棉异型板材工厂直供推荐 - 品牌宣传支持者
  • 加速Python依赖安装:使用国内镜像源优化pip install
  • UID9622/TaiGenesis 双系统确认 | 概念盗窃审计报告(这是最初的创作报告,八个月前的整套逻辑在手,请自重).
  • Flutter 三方库 github_actions_toolkit 的鸿蒙化适配指南 - 实现 GitHub Actions 高效自动化任务构建、支持日志颜色修饰与核心工具集成
  • hash和history导航区别 个别服务器为啥不支持 history 模式
  • Flutter 三方库 dynamic_config_generator 的鸿蒙化适配指南 - 实现具备全静态化环境变量注入与类型安全配置文件生成的构建基石、支持端侧多环境自动切换实战
  • 实施方法论
  • ubuntu如何设置远程工具连接