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(或类似的视图类)来显示可用的撤销/重做命令,并提供用户界面让用户执行这些操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值