我试图在一个超级简单的文本编辑器中实现一个撤消/重做功能,作为一个项目。我有一个类CommandProcessor
,它接受用户按下的按钮,如果匹配,则执行一个泛型命令,该命令调用使用该特定命令的对象类型的execute()函数,即
struct UserInteraction
{
UserInteractionType type; // this is just a enum type
Command* command;
};
case 'U':
command = new MoveLeft;
return makeCommandInteraction(command);
这是它调用的MoveLeft命令:
void MoveLeft::execute(Editor& editor)
{
// if we try to move past the amount of input, throw exception
if(editor.cursorColumn() == 1) {
throw EditorException("Already at beginning!");
} else { // otherwise, move the cursor left
editor.moveCursorLeft();
}
}
在其中,这是被调用的编辑器命令。
void Editor::moveCursorLeft()
{
column--;
}
如果用户点击ctrl + z或ctrl + a,我们会返回撤消/重做命令:return makeUndoInteraction();
或return makeRedoInteraction();
我使用两个堆栈,一个用于撤消,一个用于重做。 undoStack
存储最新的命令,当在处理器中调用时,从MoveLeft
调用撤销功能(当前只是向右移动光标),将undoStack的顶部推送到redoStack,然后弹出undoStack的顶部。 redoStack
保存最后一个撤消命令,因此,我将其存储在interaction
中,这是保存命令的类型。有了这个,我从MoveLeft
调用execute(),然后将交互推回到undoStack
这两个函数都是:
else if (interaction.type == UserInteractionType::undo)
{
try
{
interaction.command->undo(editor);
redoStack.push(undoStack.top());
undoStack.pop();
view.clearErrorMessage();
} catch (EditorException& e)
{
view.showErrorMessage(e.getReason());
}
view.refresh();
delete interaction.command; // delete command since we stored it in the stack
}
else if (interaction.type == UserInteractionType::redo)
{
try
{
interaction = redoStack.top();
interaction.command->execute(editor);
undoStack.push(interaction);
view.clearErrorMessage();
}
catch (EditorException& e)
{
view.showErrorMessage(e.getReason());
}
view.refresh();
}
现在我得到"分段错误(核心转储)"在撤消的这一行:
interaction.command->撤消(编辑);
如果我只是测试重做,我会在这一行得到一个分段错误:
interaction = redoStack.top();
两者都是try语句之后的第一行。可能导致什么呢?