新闻中心
C++如何实现命令设计模式?C++请求封装与撤销功能实现【设计模式】
命令模式在C++中通过将请求封装为Command接口对象实现解耦,支持参数化、排队、日志与撤销;Invoker调用execute()/undo()而不依赖Receiver细节,Receiver仅执行具体逻辑,命令对象应轻量、无状态或仅存必要上下文,撤销需缓存状态并用智能指针管理生命周期。

命令模式在C++中核心是把“请求”封装成对象,从而支持参数化、排队、日志、撤销等操作。关
键在于定义统一的命令接口,让调用者(Invoker)不依赖具体操作细节,而接收者(Receiver)只负责执行实际逻辑。
命令接口与具体命令类
定义抽象基类 Command,声明虚函数 execute() 和可选的 undo();每个具体操作(如打开文件、保存、撤回)派生一个命令类,内部持有对 Receiver 的引用或所需数据。
- Receiver 不直接被 Invoker 调用,而是由 Command 在 execute() 中调用其方法
- 命令对象应尽量无状态,或仅保存执行必需的最小上下文(如文件名、旧文本、坐标)
- 若需撤销,undo() 必须能恢复到 execute 前的状态,通常需在 execute 中缓存关键信息
支持撤销的命令栈管理
用 std::stack<:unique_ptr>> 管理已执行命令,每次 execute 后压入栈;调用 undo 时弹出栈顶并调用其 undo()。注意:不是所有命令都支持撤销(如“退出程序”),可加 isUndoable() 接口或用空实现。
- 撤销后通常需禁用重做(Redo),若需支持,可额外维护一个 redo 栈,在 undo 时把命令移入 redo 栈
- 避免裸指针,用智能指针管理命令生命周期,防止内存泄漏
- 命令对象一般是一次性使用的,执行/撤销后可析构,无需复用
调用者(Invoker)解耦设计
Invoker 持有 Command* 或 std::function
QoQo
QoQo是一款专注于UX设计的AI工具,可以帮助UX设计师生成用户角色卡片、用户旅程图、用户访谈问卷等。
172
查看详情
- 可扩展为支持宏命令(MacroCommand):聚合多个子命令,统一 execute/undo
- 菜单项、快捷键、按钮等 UI 元素均可作为 Invoker,绑定不同命令实例
- Invoker 可记录命令执行时间、失败重试策略,或转发给日志模块
一个简明示例:文本编辑器的撤销操作
假设 Receiver 是 TextDocument,有 insert(text) 和 deleteLast() 方法。命令类 InsertCommand 在构造时保存待插入文本,在 execute() 中调用 insert(),在 undo() 中调用 deleteLast()(前提是知道删多少字符——所以它还需缓存 length)。
- 构造 InsertCommand(doc, "hello") → 缓存 doc 和 "hello" 长度 5
- execute() → doc.insert("hello")
- undo() → doc.deleteLast(5)
- Invoker(如 Editor 类)持有一个 std::stack,每次成功 execute 后 push(std::move(cmd))
基本上就这些。命令模式在 C++ 中不复杂,但容易忽略内存管理和撤销状态一致性。只要接口清晰、职责分明,就能自然支持请求队列、事务回滚和用户级撤销功能。
以上就是C++如何实现命令设计模式?C++请求封装与撤销功能实现【设计模式】的详细内容,更多请关注其它相关文章!
# 做什么
# 双鸭山市关键词seo排名优化
# 鄂州网站建设步骤
# 临沂网站如何推广
# 盛大文学网站建设
# 罗村网站建设方案书
# 靠谱seo整站优化
# 营销推广岗位奖金
# 株洲seo外包公司
# 谷歌搜索seo站群
# 灵寿网站优化多少钱
# 执行时间
# mac
# 是由
# 调用者
# 多个
# 就能
# 若需
# 具体操作
# 如何用
# 如何实现
# red
# c++
# 栈
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
mcjs网页版流畅运行 mcjs低配电脑畅玩入口
MAC怎么让Dock栏只显示当前运行的应用_MAC终端命令实现极简Dock栏
2025-2030年全球乘用车销量预测:新能源成增长主力
深入理解J*a链表中的IPosition接口与使用
深入理解Promise链:如何在catch后中断then的执行
探索高级语言到C/C++的转译路径:以Go为例及内存管理策略
在J*a中如何使用Exception包装底层异常_异常包装与信息传递方法说明
qq游戏网页版直接玩_qq游戏免下载快速入口
Django模型中自动计算可用余额的实现方法
Win11文件资源管理器卡顿怎么修 Win11重置资源管理器进程优化响应速度【修复方法】
如何在Promise链中优雅地中断后续then执行
QQ邮箱官方邮箱登录入口 QQ邮箱网页版快速访问
知音漫客正版漫画平台_知音漫客官网账号登录
大麦的“候补”是什么意思 大麦候补购票规则【详解】
Fabric Mod开发:在1.19.3+版本中正确添加自定义物品并管理物品组
支付宝解绑银行卡步骤_支付宝如何解除绑定银行卡
Golang如何实现微服务鉴权与权限控制_Golang微服务鉴权与权限管理实践
Sublime怎么配置Nim语言环境_Sublime Nim代码高亮与补全
Win11输入法不见了怎么办_Windows11恢复语言栏显示方法
QQ邮箱官网登录入口 QQ邮箱网页版邮箱快速登录
抖音从哪里进入网页版_抖音官方入口链接
谷歌google账号怎么注册账号 谷歌账号注册官方流程
在J*a里如何理解依赖关系的方向_依赖方向在模块结构中的作用
CKEditor 5 自定义构建在React应用中渲染失败的调试与解决
CSS条件样式无法按设备触发怎么排查_media条件语句正确设置解决触发问题
cad怎么合并重叠的线段_cad清理重复重叠线条的操作方法
QQ网页版官方账号入口 QQ网页版网页版登录指南
Pandas DataFrame 高效批量赋值:告别循环与笛卡尔积误区
qq音乐在线播放入口_qq音乐电脑版登录链接
J*aScript设计模式实践_j*ascript代码优化
Golang如何实现Web文件静态资源服务器_Golang静态资源服务器开发与实践
2306选座时如何选靠窗位置_12306选座靠窗座位查看方法解析
CSS布局中意外空白:解决padding-top导致的顶部间距问题
Win10文件资源管理器“此电脑”分组怎么关 Win10恢复经典视图【技巧】
照顾宝贝2小游戏点击立即在线玩
AO3最新官网入口公告_2025AO3镜像站实时查询方法
Win11 USB传输速度慢怎么解决 Win11 USB驱动更新与设置
12306选座如何查看座位示意图_12306座位示意图解读与使用
Kafka Streams中基于消息头条件过滤消息的实现指南
韩小圈电脑版在线入口_网页版免费登录地址
MongoDB Aggregation:在嵌套对象数组中精确匹配ObjectId
C++ explicit关键字防止隐式转换_C++构造函数安全规范
内存检查:在VS Code中调试C++时的内存视图
TypeScript/J*aScript:高效查找数组中首个唯一ID对象
期待已久:小米17 Ultra、小米首款NAS本月登场
163邮箱登录密码 163邮箱忘记密码找回
uc浏览器网页版入口 uc浏览器网页版最新网址
移动端XML文件怎么转换成Excel 手机和平板上的解决方案
知音漫客官网漫画下载_知音漫客网页版阅读记录
c++中的std::forward_list和std::list有什么不同_c++ forward_list与list区别分析


2025-12-15
浏览次数:次
返回列表