Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 具有链接树结构的命令模式(使用指针)_C++_Design Patterns_Undo Redo - Fatal编程技术网

C++ 具有链接树结构的命令模式(使用指针)

C++ 具有链接树结构的命令模式(使用指针),c++,design-patterns,undo-redo,C++,Design Patterns,Undo Redo,我正在为某种二叉树结构开发一个编辑器,我需要一个撤销功能。我考虑使用命令模式来实现这一点。然而,我仍然无法找到一种方法将命令模式与我的二叉树结构结合使用 二叉树结构是通过指针组成的。所以一个节点知道它的父节点和子节点。当我现在想要添加一个节点时,我会构造一个nodead对象,将父对象作为参数,并将其传递给UndoStack。要删除现有节点,将NodeRemove对象传递给UndoStack,并将指向节点的指针作为参数。nodead和NodeRemove都必须实现undo()和redo()(其中当

我正在为某种二叉树结构开发一个编辑器,我需要一个撤销功能。我考虑使用命令模式来实现这一点。然而,我仍然无法找到一种方法将命令模式与我的二叉树结构结合使用

二叉树结构是通过指针组成的。所以一个节点知道它的父节点和子节点。当我现在想要添加一个节点时,我会构造一个
nodead
对象,将父对象作为参数,并将其传递给
UndoStack
。要删除现有节点,将
NodeRemove
对象传递给
UndoStack
,并将指向
节点的指针作为参数。
nodead
NodeRemove
都必须实现
undo()
redo()
(其中当对象放在
UndoStack
上时调用
redo()

我面临的问题是,处理删除节点后应撤消添加同一节点的情况:

  • 重做nodead
  • 重做节点删除
  • 撤消节点删除
  • 撤消nodead
  • 执行redo NodeRemove后,
    节点
    对象将被销毁。在undo NodeRemove中,可以再次构造新的
    节点
    对象,但undo NodeAd无法执行,因为它没有指向新构造的
    节点
    的指针

    我认为我试图以错误的方式使用命令模式。我可能应该销毁或构造
    节点
    对象,而不是在命令的构造函数/析构函数中,而不是在
    undo()
    /
    redo()
    中。不幸的是,我不知道如何使用这种结构,我能找到的所有示例和建议都与文本编辑或编辑没有指针的动态结构的内容有关


    有没有办法解决这个问题?

    命令模式可能不足以撤销。对于撤消,应使用memento模式

    一种选择是让您的
    命令
    对象通过某种唯一标识符(比如用
    大小表示的索引
    )引用操作数,而不是通过内存地址引用操作数,正如您所发现的,内存地址可能会波动


    然后,通过在某处(例如,
    节点
    的静态成员)维护一个
    无序的
    ,您的
    命令
    对象可以获得给定
    节点
    的当前实施例,并根据需要添加/删除/操作它。

    模式可以组合,甚至在它们内部。为您的命令同时提供一个execute方法和一个undo方法。调用命令时,将实例置于双向责任链中,具有撤消和重做方向和方法。

    如果我了解memento模式,我需要为每个状态保留图形副本。使用命令模式,我将只存储两个状态之间的实际更改。尽管创建整个图表的副本可以避免我所描述的问题,但我很好奇是否有办法解决这个问题,并且只跟踪更改。我同意这是一种选择。谢谢你的建议。我不明白你想指出什么。您将一个实例放入双向责任链的确切含义是什么?到目前为止,我只知道对命令模式的粗略解释。