如何创建“撤消”选项在 C++ 中?

发布于 2024-08-30 13:07:18 字数 160 浏览 3 评论 0原文

我需要创建一个函数来撤消之前的任务/添加/更改。我如何在 Borland C++ 中做到这一点?

(该程序使用“列表”将文本字符串存储在文本文件中。除非我使用我创建的保存功能,否则它会被存储然后删除。)

顺便说一句,我的意思是在一个简单的控制台应用程序中创建一个撤消功能。

I need to create a function that undoes the previous task/addition/change. How do I do this in Borland C++?

(The program stores strings of text in a text file using "list". It is stored and then erased unless I use the save-function I've created.)

I meant creating an undo function in a simple console application by the way.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

誰認得朕 2024-09-06 13:07:18

我会给出另一个答案,但我认为到目前为止覆盖范围还不够。

这个主题绝非微不足道,谷歌搜索它会返回大量结果。许多应用程序都实现“撤消”操作,并且有许多变体。

有两种设计模式可以帮助我们:

  • Command:它是操作的具体化
  • Memento:它包含存储状态(通常意味着某种形式的序列化

Command 模式在图形环境中大量使用,因为通常有多种方法来完成操作。以 Microsoft Word 中的保存为例:

  • 您可以单击保存图标,
  • 您可以进入文件菜单并单击保存
  • 你使用快捷键,通常是CTRL+S

,当然保存可能是通过另存为来实现的。

这里的命令模式的优点是双重的:

  • 您可以创建一个对象堆栈,
  • 您可以要求每个对象实现撤消操作

现在,存在各种适合的问题。 code>undo

  • 某些操作无法撤消(例如,考虑 Linux 上的 rm 或 Windows 上的清空垃圾箱操作)
  • 某些操作难以撤消,或者它可能不自然(您需要存储一些状态,该对象通常会被销毁,但在这里您需要将其实际存储在撤消操作的命令中)
  • 通常我们将撤消/重做视为堆栈,某些软件(主要是图形)建议撤消项目而不实际撤消之后所做的事情,这是更难实现的,特别是当新的操作建立在要撤消的操作之上时......

因为存在各种问题,有多种策略:

  • 对于简单的命令,您可能会考虑实现撤消(例如,添加字符可以通过删除来撤消)
  • 对于更复杂的命令,您可能会考虑实现撤消以恢复先前的状态(这就是Memento 启动)
  • 如果您有很多复杂的命令,这可能意味着很多 Memento 会占用空间,那么您可以使用一种只记住一个 Memento 的方法。 em>快照每 10 或 20 个命令,然后重做从最新快照到撤消的命令的命令

事实上,您可以混合使用 CommandMemento 闲暇时,取决于系统的具体情况以及两者的复杂性。

我只会考虑撤消开始时执行的最后一个操作(然后使用一堆操作)。撤消用户希望的任何操作的功能要复杂得多。

I'll give yet another answer, but I think that the coverage has been insufficient so far.

The subject is far from trivial, and googling it returns a good number of results. Many applications implement a "undo" operation, and there are many variants.

There are 2 design patterns which can help us out here:

  • Command: it's a reification of an action
  • Memento: which consists in storing state (usually implies some form of serialization)

The Command pattern is heavily used in graphic environments because there is usually various ways to accomplish an action. Think of save in Microsoft Word for example:

  • you can click on the save icon
  • you can go into File menu and click on Save
  • you use the shortcut, typically CTRL+S

And of course save is probably implemented in term of save as.

The advantage of the Command pattern here is twofold:

  • you can create a stack of objects
  • you can ask every object to implement an undo operation

Now, there are various issues proper to undo:

  • some operations cannot be undone (for example, consider rm on Linux or the empty trash bin action on Windows)
  • some operations are difficult to undo, or it may not be natural (you need to store some state, the object is normally destroyed but here you would need to actually store it within the command for the undo action)
  • generally we think of undo/redo as a stack, some software (graphics mainly) propose to undo items without actually undoing what has been done afterward, this is much more difficult to achieve, especially when the newer actions have been built on top of the to-undo one...

Because there are various problems, there are various strategies:

  • For a simple Command, you might consider implementing an undo (for example, adding a character can be undone by removing it)
  • For a more complex Command, you might consider implementing the undo as restoring the previous state (that's where Memento kick in)
  • If you have lots of complex Command, that could mean lots of Mementos which consumes space, you can then use an approach which consists in only memorizing one Snapshot every 10 or 20 commands, and then redoing the commands from the latest snapshot up to the undone command

In fact, you can probably mix Command and Memento at leisure, depending on the specifics of your system and thus the complexity of either.

I would only considering undoing the last action executed to begin with (using a stack of action then). The functionality of undoing whatever action the user wishes is much more complicated.

我ぃ本無心為│何有愛 2024-09-06 13:07:18

要实现撤消,您需要在应用程序中创建一个“操作堆栈”。不过,有两种基本方法:

  1. 了解您的基线(上次保存文件的时间,或自创建文件以来),记住所做的每一项更改,以便在需要撤消某些操作时将其丢弃“最顶层”项目并根据基线重新生成当前视图以及所有更改。单击“重做”,然后将该项目放回堆栈中。这样做的一个附带好处是能够轻松地删除堆栈中任何位置的项目,而不会弄乱其他撤消/重做选项,尽管需要特别小心以确保“更高”状态的应用符合用户的预期。< /p>

  2. 对于每个操作,存储对先前状态所做的更改以及在撤消时恢复先前状态所需的更改。现在,当用户单击“撤消”时,只需执行“撤消”步骤即可。单击“重做”时,重新应用所做的更改。在某些情况下,“撤消”步骤将是“这就是之前的样子”,但是如果您希望允许用户删除不在堆栈顶部的项目,然后需要删除上面的内容,则可能会造成严重破坏 对于每个操作,存储

正确的选择取决于很多因素,包括您可以/将携带多少数据。选项 #1 在某种意义上更容易,但如果操作堆栈很大,撤消任何操作可能会变得非常慢。

To implement Undo, you need to create an "action stack" in your application. There are two basic approaches, though:

  1. Knowing your baseline (the last time the file was saved, or since the file was created), remember every single change that was made so that when something needs to be undone you just throw away the "top-most" item and regenerate the current view from the baseline plus all of the changes. Clicking "Redo" then just puts that item back on the stack. This has a side benefit of being able to trivially remove items anywhere in the stack without messing up other undo/redo options, although there will be special care needed to make sure that the application of "higher" states is as the user intended.

  2. For each action, store off the change that was made to the previous state as well as the change that would be necessary to restore that previous state if you were to undo. Now when the user clicks "Undo," just do the "undo" steps. When clicking "Redo," reapply the changes that were made. In some cases the "Undo" steps will be "here's what the thing looked like before," but that can cause havoc if you want to allow users to remove items that are not on the top of the stack and then need to remove something above it.

The proper choice depends on a lot of factors, including how much data you can/will carry around. Option #1 is in some sense easier but it could become very slow to undo anything if the action stack is large.

沒落の蓅哖 2024-09-06 13:07:18

另请参阅纪念品图案。有时,撤销操作的命令中必须包含的情报非常复杂。例如,在绘图程序中绘制对象。仅存储备忘录然后从该备忘录恢复以实现撤消会更容易。

Also see the memento pattern. Sometimes the intelligence that must go into a command to undo an operation is pretty involved. Drawing objects in a paint program for example. It can be easier just to store a memento and then restore from that memento to implement undo.

甜点 2024-09-06 13:07:18

您可以存储状态快照。状态是操作可以修改的数据集。单击“撤消”时,当前状态将替换为之前的状态。实际上,这不是一项简单的任务,尤其是在状态很复杂的情况下。

You can store snapshots of state. State is the set of data that an action can modify. When you click undo, the current state is replaced by previous. Actually it is not a trivial task, especially if the state is complex.

雨轻弹 2024-09-06 13:07:18

我最近一直在尝试这个主题。如果您不需要二进制兼容性,请查看 https://github.com/d-led /undoredo-cpp

I've been experimenting lately on that subject. In case you don't need binary compatibility, check out https://github.com/d-led/undoredo-cpp

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文