讲师中心 微信公众号

工具推荐

视频效率加速
立刻MV
立刻MV

低成本歌曲 MV、视频生成

Seko
Seko

AI短剧一键生成成片

剧云
剧云

中文短剧剧本制作平台

AniShort
AniShort

AI短剧协同制作平台

C++怎么实现状态机_C++逻辑控制教程【建模】

阿伟君_9307

阿伟君_9307

发布时间:2026-03-04 14:21:30

|

846人浏览过

|

来源于php中文网

原创

状态机应优先用类封装,因需管理上下文、复用逻辑及响应外部事件;函数指针数组易越界且难控生命周期;含数据成员或需事件钩子时必须用类;switch+enum class+default断言更安全。

c++怎么实现状态机_c++逻辑控制教程【建模】

状态机该用类封装还是函数指针数组

用类封装更可控,函数指针数组容易失控。C++里状态机不是“选个结构就行”,而是看状态迁移是否带上下文、是否需复用、是否要响应外部事件。

常见错误现象:std::function 存一堆匿名 lambda 导致对象生命周期难管理;用 void(*)() 函数指针数组时,状态跳转写成 states[next_state]() 却忘了检查 next_state 越界。

  • 有数据成员(比如计数器、缓存 buffer)→ 必须用类,状态函数作为 private 成员方法
  • 纯跳转逻辑(如协议解析的 3 个固定状态)→ 可用 std::array<:function>, N></:function>,但初始化必须全非空,否则调用时报 std::bad_function_call
  • 需要从外部触发事件(如 on_keypress())→ 类里加 virtual 事件钩子,别把事件分发逻辑塞进状态函数内部

怎么避免状态跳转时漏掉 break 或 return

用 switch 写状态机最常翻车的地方不是语法错,是少写 break 导致意外穿透,或在 if-else if 链里忘了兜底 else 处理非法状态。

使用场景:嵌入式轮询式状态机、游戏 AI 的行为切换。

立即学习“C++免费学习笔记(深入)”;

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 强制用 enum class State { Idle, Running, Paused };,编译器能帮你 catch 未覆盖枚举值(配合 -Wswitch-enum)
  • 每个 case 块末尾加 // fallthrough 注释,没这行就警告 —— GCC/Clang 都支持 -Wimplicit-fallthrough
  • 别写 if (state == Idle) { ... } else if (state == Running) { ... },改用 switch (state) + default: assert(false);,运行时暴露问题比静默跳到未知分支强

std::variant + std::visit 能不能替代传统状态机

能,但只适合状态极少(≤4)、迁移逻辑极简、且不关心执行顺序的场景。它本质是“状态数据建模”,不是“控制流建模”。

性能影响:每次 std::visit 有间接调用开销,比直接调用成员函数慢 10%–20%;兼容性上 C++17 起可用,但 MSVC 2017 初版对 std::variant 的 SFINAE 支持有 bug。

  • 适用:配置解析器的状态(ReadingKey / ReadingValue / Done),每个状态只干一件事,无循环或条件跳转
  • 不适用:TCP 连接状态机(SYN_SENT → ESTABLISHED → CLOSE_WAIT → …),迁移路径多、条件耦合深
  • 参数差异:std::variant 存的是“当前状态的数据快照”,不是“可执行的行为”;想在状态里存回调?得塞 std::function,又回到生命周期问题

调试状态机时怎么看清实际走哪条路径

别靠 print,print 容易被优化掉或淹没在日志里。真正在意路径,就得让状态跳转本身可观察、可拦截。

容易踩的坑:在每个状态函数开头打 printf("in Running\n"),结果发现输出顺序和预期不符——其实是异步任务调度或重入导致的。

  • 加一层薄薄的跳转记录:在基类里定义 virtual void on_state_changed(State from, State to),派生类按需 override 记录到环形缓冲区
  • 用 __builtin_return_address(0) + backtrace_symbols 抓调用栈(仅调试版),比字符串匹配靠谱
  • 关键状态点加 assert(state_ == ExpectedState),别等出错了才查——状态机的错往往延迟暴露

复杂点在于状态可能被多个线程修改,或被中断打断。这时候加锁不是解法,真正要的是明确“谁负责驱动状态变迁”,把驱动逻辑收口到单一入口点,比如 process_event(const Event& e)。其他地方只读状态,不写。

热门AI工具

更多
Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

相关专题

更多
python中print函数的用法
python中print函数的用法

python中print函数的语法是“print(value1, value2, ..., sep=' ', end=' ', file=sys.stdout, flush=False)”。本专题为大家提供print相关的文章、下载、课程内容,供大家免费下载体验。

3420

2023.09.27

python print用法与作用
python print用法与作用

本专题整合了python print的用法、作用、函数功能相关内容,阅读专题下面的文章了解更多详细教程。

269

2026.02.03

switch语句用法
switch语句用法

switch语句用法:1、Switch语句只能用于整数类型,枚举类型和String类型,不能用于浮点数类型和布尔类型;2、每个case语句后面必须跟着一个break语句,以防止执行其他case的代码块,没有break语句,将会继续执行下一个case的代码块;3、可以在一个case语句中匹配多个值,使用逗号分隔;4、Switch语句中的default代码块是可选的等等。

1071

2023.09.21

Java switch的用法
Java switch的用法

Java中的switch语句用于根据不同的条件执行不同的代码块。想了解更多switch的相关内容,可以阅读本专题下面的文章。

1457

2024.03.13

printf用法大全
printf用法大全

php中文网为大家提供printf用法大全,以及其他printf函数的相关文章、相关下载资源以及各种相关课程,供大家免费下载体验。

928

2023.06.20

fprintf和printf的区别
fprintf和printf的区别

fprintf和printf的区别在于输出的目标不同,printf输出到标准输出流,而fprintf输出到指定的文件流。根据需要选择合适的函数来进行输出操作。更多关于fprintf和printf的相关文章详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1029

2023.11.28

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2438

2023.09.20

java中break的作用
java中break的作用

本专题整合了java中break的用法教程,阅读专题下面的文章了解更多详细内容。

3280

2025.10.15

Postman身份认证怎么配置
Postman身份认证怎么配置

本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

80

2026.11.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn