新闻中心

C++怎么实现一个状态模式(State)_C++设计模式与状态模式实现

2025-11-13
浏览次数:
返回列表
状态模式通过封装不同状态行为并实现运行时切换,使对象在内部状态改变时改变其行为。示例中,DocumentContext根据当前DocumentState执行edit和publish操作,DraftState允许编辑并可转为PublishedState,而PublishedState禁止编辑且保持发布状态,避免了条件判断,提升了扩展性与维护性。

c++怎么实现一个状态模式(state)_c++设计模式与状态模式实现

状态模式(State Pattern)是一种行为型设计模式,它允许对象在内部状态改变时改变其行为。C++中实现状态模式的关键是将状态封装成独立的类,并通过委托的方式让上下文(Context)对象在运行时切换状态对象,从而改变其行为。

状态模式的核心思想

将与特定状态相关的行为局部化到对应的状态类中,避免在上下文中使用大量的条件判断语句(如 if/else 或 switch)。当对象的内在状态改变时,它的行为也随之改变,看起来就像改变了类一样。

  • Context:拥有一个当前状态对象的引用,所有状态相关的请求都委托给当前状态对象处理。
  • State:定义一个接口,封装与 Context 的某个状态相关的行为。
  • ConcreteStateA/B:具体的状态实现类,实现 State 接口中定义的行为。

基本结构代码实现

下面是一个简单的 C++ 示例,模拟一个文档编辑器的状态切换(例如“草稿”和“已发布”状态):

#include <iostream>
#include <memory>

// 前向声明
class DocumentContext;

// 抽象状态类
class DocumentState {
public:
    virtual ~DocumentState() = default;
    virtual void edit(DocumentContext& ctx) = 0;
    virtual void publish(DocumentContext& ctx) = 0;
};

// 具体上下文类(需要前向声明后定义)
class DocumentContext {
private:
    std::shared_ptr<DocumentState> currentState;

public:
    DocumentContext(std::shared_ptr<DocumentState> state)
        : currentState(state) {}

    void setState(std::shared_ptr<DocumentState> state) {
        currentState = state;
    }

    void edit() {
        currentState->edit(*this);
    }

    void publish() {
        currentState->publish(*this);
    }

    std::shared_ptr<DocumentState> getState() const {
        return currentState;
    }
};

// 草稿状态
class DraftState : public DocumentState {
public:
    void edit(DocumentContext& ctx) override {
        std::cout << "正在编辑文档(草稿状态)。\n";
    }

    void publish(DocumentContext& ctx) override {
        std::cout << "提交文档审核...\n";
        // 模拟审核通过,切换为已发布状态
        ctx.setState(std::make_shared<PublishedState>());
    }
};

// 已发布状态
class PublishedState : public DocumentState {
public:
    void edit(DocumentContext& ctx) override {
        std::cout << "文档已发布,无法编辑!\n";
    }

    void publish(DocumentContext& ctx) override {
        std::cout << "文档已经是发布状态。\n";
    }
};

使用示例

测试上面的状态切换逻辑:

Shoping购物网源码 Shoping购物网源码

该系统采用多层模式开发,这个网站主要展示女装的经营,更易于网站的扩展和后期的维护,同时也根据常用的SQL注入手段做出相应的防御以提高网站的安全性,本网站实现了购物车,产品订单管理,产品展示,等等,后台实现了动态权限的管理,客户管理,订单管理以及商品管理等等,前台页面设计精致,后台便于操作等。实现了无限子类的添加,实现了动态权限的管理,支持一下一个人做的辛苦

Shoping购物网源码 0 查看详情 Shoping购物网源码
int main() {
    auto draft = std::make_shared<DraftState>();
    DocumentContext doc(draft);

    doc.edit();      // 输出:正在编辑文档(草稿状态)
    doc.publish();   // 输出:提交文档审核...

    doc.edit();      // 输出:文档已发布,无法编辑!
    doc.publish();   // 输出:文档已经是发布状态。

    return 0;
}

优点与适用场景

这种实现方式的优点在于:

  • 消除复杂的条件判断:不同状态的行为被分散到各自的类中,代码更清晰。
  • 易于扩展新状态:添加新的状态只需新增一个类并实现接口,符合开闭原则。
  • 状态转换显式可控:可以在状态内部或上下文中控制何时切换状态。

适用于有明确状态转换逻辑的系统,比如订单状态机、游戏角色状态、UI 控件状态等。

基本上就这些。状态模式通过多态和组合,把变化的状态行为隔离,让程序更灵活、可维护。

以上就是C++怎么实现一个状态模式(State)_C++设计模式与状态模式实现的详细内容,更多请关注其它相关文章!


# 前向  # 怎样让网站优化的方式  # 东北人学seo  # seo文案专员面试  # 佛山微信营销推广多少钱  # 形容营销推广的词语  # 济南专业网站优化seo公司  # 兴县网站推广咨询  # 短视频推广营销费用高吗  # 知名的百度网站优化软件  # seo内容写作计费  # 是一个  # 在内部  # 类中  # c++  # 如何实现  # 如何使用  # 多态  # 实现了  # 购物网  # 文档  # red  # stream  # switch  # ios  # ai  # 状态模式 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: vivo手机参数配置怎么增强信号_vivo手机参数配置信号增强方法  狙击外星人小游戏开始_狙击外星人小游戏立即开始  谷歌google账号怎么注册账号 谷歌账号注册官方流程  怎么在浏览器上运行HTML文件_浏览器运行HTML文件技巧【技巧】  微信语音通话掉线如何解决 微信语音通话稳定优化方法  如何在J*a中实现统一对象行为接口_项目大型化时的接口规范化  荣耀Play7TPro怎样在信息App置顶客服对话_iPhone荣耀Play7TPro信息App置顶客服对话【优先查看】  PS5 Pro有点优势但不多! 《燕云十六声》PS5平台与PC性能画面对比  PowerPoint如何制作滚动字幕结尾彩蛋_PowerPoint路径动画实现平滑滚动字幕效果  如何在 Excel Online 和 Google 表格中更改日期格式  如何使 Jest 模拟函数默认抛出错误以提高测试效率  QQ邮箱登录官网首页 腾讯QQ邮箱网页入口  MongoDB Aggregation:在嵌套对象数组中精确匹配ObjectId  CSS条件样式无法按设备触发怎么排查_media条件语句正确设置解决触发问题  Go RPC HTTP服务正确实现与常见陷阱解析  C++如何连接MySQL数据库_C++使用Connector/C++操作MySQL数据库教程  Django表单验证失败时保留用户输入数据的最佳实践  网易大神怎么保存别人动态的图片_网易大神动态图片保存方法  荒野行动PC版怎么注册_荒野行动PC版账号注册详细流程图文教程  J*aScript 字符串标签转换:使用正则表达式高效替换  Lar*el DB::listen 事件中的查询执行时间单位解析  c++ 命名空间怎么用 c++ namespace使用指南  腾讯QQ邮箱官方网站_QQ邮箱网页版在线登录  AO3最新官网入口公告_2025AO3镜像站实时查询方法  J*aScript map 方法中处理循环元素为空数组的策略  Lar*el用户头像管理:实现图片缩放、存储与旧文件安全删除的最佳实践  yandex入口引擎手机版 yandex安卓版下载入口  Win11怎么开启卓越性能模式 Win11电源选项启用高性能释放硬件潜力【方法】  Flexbox布局实践:实现粘性导航栏与底部固定页脚  抖音创作助手登录入口_抖音创作辅助工具官网直达  J*aScript异步迭代器_j*ascript异步遍历  React/Next.js中实现列表项的动态移动与状态管理:兼论唯一键的重要性  Highcharts 雷达图径向轴标签定制指南:利用多Y轴实现数值标注  Surface怎么安装系统 微软Surface Pro U盘重装win11教程  zookeeper 都有哪些功能?  一加 14R 快充无反应_一加 14R 充电优化  在React函数组件中利用原生HTML5进行邮箱地址验证  Yandex官网搜索引擎免登录_俄罗斯Yandex一键直达入口  Win10如何清理注册表垃圾 Win10手动清理无效注册表【技巧】  C++如何操作大型数据集_使用C++流式处理(Streaming)技术避免一次性加载大文件  4399免费游戏网址入口 4399小游戏免费入口点开即玩  漫蛙漫画官方首页 漫蛙2漫画在线阅读入口  J*a应用集成GitHub CLI与API认证指南  如何使用spryker/configurable-bundles-products-resource-relationship模块解决复杂产品捆绑关系难题  铁路12306卧铺选择攻略 铁路12306下铺座位预定技巧  文心一言怎样用批量生成做多版文案_文心一言用批量生成做多版文案【批量创作】  JUnit5/Mockito:优雅测试内部依赖与异常处理的实践  Python字典中优雅地迭代剩余元素的方法  ACG动漫手机版官网入口 手机ACG动漫APP在线观看正版  使用Pandas转换并合并DataFrame:多列映射至统一结构 

搜索