C++ 撤销重做

在C++中实现redo/undo功能通常涉及到对命令或操作的历史进行追踪。这可以通过命令模式(Command Pattern)和内存中的栈结构来实现。命令模式允许你将操作封装为对象,这些对象可以被存储、排队、参数化、传递、调用,并且可以支持撤销(undo)和重做(redo)操作。
下面是一个简化的redo/undo实现的例子:

1、定义命令接口

class Command {  
public:  virtual ~Command() {}  virtual void redo() = 0;  virtual void undo() = 0;  
};

2、实现具体命令

class ConcreteCommand : public Command {  
private:  // 假设这里有一个状态需要被修改  int state;  public:  ConcreteCommand(int initialState) : state(initialState) {}  void redo() override {  // 执行操作,修改状态  state++;  // ... 其他逻辑  }  void undo() override {  // 撤销操作,还原状态  state--;   // ... 其他逻辑  }  };

3、管理历史命令

class CommandHistory {  
private:  std::deque<std::unique_ptr<Command>> undoStack;  std::deque<std::unique_ptr<Command>> redoStack;  public:  void execute(std::unique_ptr<Command> command) {  command->redo();  undoStack.push_back(std::move(command));  // 清空redo栈,因为执行了新命令  redoStack.clear();  }  void undo() {  if (!undoStack.empty()) {  auto command = std::move(undoStack.back());  undoStack.pop_back();  command->undo();  redoStack.push_front(std::move(command));  }  }  void redo() {  if (!redoStack.empty()) {  auto command = std::move(redoStack.front());  redoStack.pop_front();  command->redo();  undoStack.push_back(std::move(command));  }  }  
};

4、外部执行命令

int main() {  CommandHistory history;  // 创建一个命令并执行它  auto cmd = std::make_unique<ConcreteCommand>(0);  history.execute(std::move(cmd));  // 撤销操作  history.undo();  // 重做操作  history.redo();  return 0;  
}

请注意,上面的代码是一个简化的例子,用于说明redo/undo功能的基本结构。在实际应用中,你可能需要处理更复杂的场景,比如命令之间的依赖关系、命令的合并、命令的持久化存储等。
此外,你也可以考虑使用现有的库来实现redo/undo功能,例如Qt框架中的QUndoStack类,它提供了更高级别的抽象和更多的功能。

QUndoStack介绍:
QUndoStack是Qt框架中用于实现撤销/重做(undo/redo)功能的一个类。它允许你管理一系列的命令(通常是 QUndoCommand 或其子类),这些命令可以被执行、撤销或重做。下面是一个使用 QUndoStack 的基本示例,以及一些重要的概念:

基本概念
QUndoCommand:这是表示一个可撤销操作的基类。你需要创建QUndoCommand的子类来定义你的具体操作。
QUndoStack:这是一个命令栈,它管理着一系列的QUndoCommand对象。你可以向栈中添加命令,然后执行、撤销或重做这些命令。

使用步骤
1、创建一个继承自QUndoCommand的类,并在其中实现 redo() 和 undo() 方法。这两个方法分别定义了执行和撤销操作的具体行为。
2、在你的主窗口或控制器类中,创建一个QUndoStack的实例。
3、当你执行一个操作时,创建一个自定义的QUndoCommand对象,并将其 push() 到 QUndoStack 中。这会将命令添加到栈中,但不会立即执行它。
4、你可以通过调用QUndoStack的undo()和redo()方法来撤销和重做命令。你也可以使用 QUndoView(或类似的视图类)来显示可用的撤销/重做命令,并提供用户界面让用户执行这些操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/855275.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

stm32f103 HAL库 HC-SR04测距

目录 一、实现测距二、添加TIM3控制LED根据距离以不同频率闪烁三、观察时序Modebus协议12路超声波雷达设计方案1. 系统架构设计2. 硬件设计3. 软件设计4. 通信协议设计5. 用户接口6. 安全和冗余7. 测试和验证8. 电源和物理封装9. 文档和支持 一、实现测距 配置时钟 配置定时器…

vue部署宝塔nginx配置(获取用户ip地址、反代理访问api接口、websocket转发)

以下配置为我自己的需求&#xff0c;因人而异&#xff0c;如果只是单纯的前端非交互页面&#xff0c;可以不用修改配置。 代码及注释&#xff0c;如下&#xff1a; #解决vue-router设置mode为history&#xff0c;去掉路由地址上的/#/后nginx显示404的问题location / {proxy_htt…

多模态大模型通用模式

MM-LLMs&#xff08;多模态大模型&#xff09;是目前比较新的和实用价值越发显著的方向。其指的是基于LLM的模型&#xff0c;具有接收、推理和输出多模态信息的能力。这里主要指图文的多模态。 代表模型&#xff1a;GPT-4o、Gemini-1.5-Pro、GPT-4v、Qwen-VL、CogVLM2、GLM4V、…

Ptrade和QMT的区别,怎么获取合适的量化交易软件?

​Ptrade和QMT的适用人群 交易活跃用户 量化爱好者已经专业量化投资者 高净值个人或机构 Ptrade和QMT的区别 回测和交易频率 Ptrade回测和交易只支持分钟级和日线级别的频率&#xff0c;而QMT支持tick级、分钟级、5分钟级、10分钟级、日线、周线、月线等。 使用QMT进行回…

Docker overlay磁盘使用100%处理方法overlay 100%

一、问题描述 服务器上运行了几个docker容器,运行个一周就会出现overlay 100%的情况&#xff0c;经查找&#xff0c;是容器里生成了很多core.xxx的文件导致的。 二、解决方法 首先通过以下命令查看&#xff1a; df -h 可以看的overlay已经100%了&#xff0c;进入到/var/lib/d…

数据库面试题-MySQL

数据库面试题-MySQL 1、数据库的三大范式是什么?2、MySQL数据库引擎有哪些?3、InnoDB与MyISAM的区别?4、数据库事务是什么?ACID是什么?5、什么是索引?6、SQL优化手段有哪些?7、简单说一说drop、delete和truncate的区别?8、什么是视图?9、什么是内联接、左外联接、右外…

计算机网络实验(9):路由器的基本配置和单臂路由配置

一、 实验名称 路由器的基本配置和单臂路由配置 二、实验目的&#xff1a; &#xff08;1&#xff09;路由器的基本配置&#xff1a; 掌握路由器几种常用配置方法&#xff1b; 掌握采用Console线缆配置路由器的方法&#xff1b; 掌握采用Telnet方式配置路由器的方法&#…

Java | Leetcode Java题解之第148题排序链表

题目&#xff1a; 题解&#xff1a; class Solution {public ListNode sortList(ListNode head) {if (head null) {return head;}int length 0;ListNode node head;while (node ! null) {length;node node.next;}ListNode dummyHead new ListNode(0, head);for (int subL…

26 种 prompt 套路,驯服大模型

节前&#xff0c;我们组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。 针对大模型技术趋势、算法项目落地经验分享、新手如何入门算法岗、该如何准备面试攻略、面试常考点等热门话题进行了深入的讨论。 总结链接如…

封装音视频编解码和渲染的动态链接库编译和测试

1.动态链接库的编译 生成了以下几个文件 我们把生成的lib文件复制到lib文件夹中 其余三个文件不变动 2.进行测试看是否可以用生成的xcodec.lib库文件里的接口函数 以上是重新创建的新项目&#xff0c;导入了xcodec.lib&#xff0c;其他配置同以前项目 库测试结果 运行显示我们…

qt登录和闹钟实现

qt实现登录 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);// 去掉头部this->setWindowFlag(Qt::FramelessWindowHint);// 去掉空白部分this->s…

栈(Stack)

目录 一.栈&#xff08;Stack&#xff09; 1.概念 2.栈的使用 3.栈的模拟实现 二.栈相关习题 1.逆波兰表达式求值 &#xff08;1&#xff09;链接 &#xff08;2&#xff09;解析 &#xff08;3&#xff09;题解 2.括号匹配 &#xff08;1&#xff09;链接 &#xff…

计算机网络——传输层重要协议(TCP、UDP)

一、常见名词解释 IP地址&#xff1a;IP地址主要用于标识网络主机、其他网络设备&#xff08;如路由器&#xff09;的网络地址&#xff0c;即IP地址用于定位主机的网络地址&#xff1b; IP地址是一个32位的二进制数&#xff0c;通常被分割为4个 8位⼆进制数&#xff08;也就是…

构建基于 LlamaIndex 的RAG AI Agent

I built a custom AI agent that thinks and then acts. I didnt invent it though, these agents are known as ReAct Agents and Ill show you how to build one yourself using LlamaIndex in this tutorial. 我构建了一个自定义的AI智能体&#xff0c;它能够思考然后行动。…

京东618 :AI总裁数字人、京东Apple Vision Pro版亮相

2004年6月18日&#xff0c;刚刚转型电商才半年的京东&#xff0c;用最互联网的方式为忠实粉丝打造了一场价格降到“难以置信”的店庆促销活动&#xff0c;这场促销活动还有一个很具有当年网络小说特质的名字——“月黑风高”。 2024年京东618&#xff0c;早已成为一场亿万消费…

泛微开发修炼之旅--20关于Ecology中如何查询正文文件的物理文件,并修改正文中的内容的解决方案

文章链接地址&#xff1a;20关于Ecology中如何查询正文文件的物理文件&#xff0c;并修改正文中的内容的解决方案

Linux系统编程——网络编程

目录 一、对于Socket、TCP/UDP、端口号的认知&#xff1a; 1.1 什么是Socket&#xff1a; 1.2 TCP/UDP对比&#xff1a; 1.3 端口号的作用&#xff1a; 二、字节序 2.1 字节序相关概念&#xff1a; 2.2 为什么会有字节序&#xff1a; 2.3 主机字节序转换成网络字节序函数…

C语言程序设计-10 指针

指针是&#xff23;语言中广泛使用的一种数据类型。运用指针编程是&#xff23;语言最主要的风格之一。利用指针变量可以表示各种数据结构&#xff1b;能很方便地使用数组和字符串&#xff1b;并能象汇编语言一样 处理内存地址&#xff0c;从而编出精练而高效的程序。指针极大地…

C语言 指针——字符数组与字符指针:字符串的输入和输出

目录 逐个字符输入输出字符串 整体输入输出字符串 用scanf输入/输出字符串 用gets输入/输出字符串 用scanf输入/输出字符串 用gets输入/输出字符串 逐个字符输入输出字符串 #define STR_LEN 80 char str[STR_LEN 1 ]; 整体输入输出字符串 用scanf输入/输出字符串 用gets…

鸿蒙开发:【启动指定页面】

启动指定页面 当PageAbility的启动模式设置为单例时&#xff08;具体设置方法和典型场景示例见[PageAbility的启动模式]&#xff0c;缺省情况下是单实例模式&#xff09;&#xff0c;若PageAbility已被拉起&#xff0c;再次启动PageAbility会触发onNewWant回调&#xff08;即非…