我正在为某种二叉树结构开发一个编辑器,我需要有一个撤销功能。我想过使用命令模式来实现这一点。但是,我还没有找到一种方法来使用命令模式和我的二叉树结构。
二叉树结构由指针组成。因此节点知道其父节点及其子节点。当我现在想要添加节点时,我将构造一个{parent}作为参数的NodeAdd
对象,并将其传递给UndoStack
。为了删除现有节点,NodeRemove
对象将通过指向UndoStack
作为参数的指针传递给Node
。 NodeAdd
和NodeRemove
都必须实现undo()
和redo()
(当redo()
上放置对象时调用UndoStack
)。
我面临的问题是,处理删除节点然后添加同一节点的情况应该撤消:
执行重做NodeRemove 后,Node
对象将被销毁。在 undo NodeRemove 中,可以再次构造新的Node
对象,但是 undo NodeAdd 无法执行,因为它没有指向新构造的{ {1}}。
我想我试图以错误的方式使用命令模式。我可能应该在命令的构造函数/析构函数中销毁或构造Node
对象,而不是Node
/ undo()
。不幸的是,我不知道如何使用这种结构做到这一点,我能找到的所有示例和建议都与文本编辑或编辑有关指针的动态结构有关。
任何想法如何处理这个问题?
答案 0 :(得分:1)
命令模式可能不足以进行撤消。对于撤消,您应该使用memento模式。
答案 1 :(得分:1)
一个选项是让您的Command
个对象通过一些唯一标识符(比如表示为size_t
的索引)而不是内存地址来引用它们的操作数,正如您所发现的那样,可以起伏不定。
然后,通过在某处保持unordered_map< size_t, Node* >
(比如说Node
的静态成员),您的Command
个对象可以获得给定Node
的当前实例根据需要添加/删除/操作。
答案 2 :(得分:0)
即使在自身内部,也可以组合模式。为命令提供执行方法和撤消方法。调用Command时,将实例放入双向责任链中,具有撤消和重做方向和方法。