簡體   English   中英

如何在C ++中創建“撤消”?

[英]How do I create “undo” in C++?

我需要創建一個撤消上一個任務/添加/更改的函數。 我如何在Borland C ++中執行此操作?

(程序使用“list”將文本字符串存儲在文本文件中。除非我使用我創建的保存功能,否則它將被存儲然后被刪除。)

我的意思是在簡單的控制台應用程序中創建一個撤銷功能。

我會給出另一個答案,但我認為到目前為止覆蓋范圍還不夠。

這個主題遠非微不足道,谷歌搜索返回了大量的結果。 許多應用程序實現“撤消”操作,並且存在許多變體。

有兩種設計模式可以幫助我們:

  • Command :它是一個動作的具體化
  • Memento :包含存儲狀態(通常意味着某種形式的序列化)

Command模式在圖形環境中大量使用,因為通常有各種方法來完成操作。 想想在Microsoft Word中保存例如:

  • 您可以單擊保存圖標
  • 您可以進入“ 文件”菜單並單擊“ 保存”
  • 您使用快捷方式,通常是CTRL + S.

當然, 保存可能是在保存時實現的。

這里Command模式的優點有兩個:

  • 你可以創建一堆對象
  • 您可以要求每個對象實現undo操作

現在,有各種適當的問題可以undo

  • 某些操作無法撤消(例如,考慮Linux上的rm或Windows上的空垃圾桶操作)
  • 有些操作很難撤消,或者它可能不自然(你需要存儲一些狀態,對象通常會被銷毀,但在這里你需要將它實際存儲在命令中以進行撤消操作)
  • 通常我們認為undo / redo是一個堆棧,一些軟件(主要是圖形)建議撤消項目而不實際撤消之后所做的事情,這要實現起來要困難得多,尤其是當新的動作建立在撤消一個......

因為存在各種問題,所以有各種策略:

  • 對於簡單的Command,您可以考慮實現撤消(例如,添加角色可以通過刪除來撤消)
  • 對於更復雜的Command,您可以考慮將undo實現為恢復之前的狀態( Memento啟動時)
  • 如果你有很多復雜的命令,這可能意味着許多消耗空間的Memento ,你可以使用一種方法,即每10或20個命令只記憶一個快照 ,然后將命令從最新的快照重做到撤消命令

事實上,您可以在閑暇時混合使用CommandMemento ,具體取決於系統的具體情況,以及任何一種的復雜性。

我只考慮撤消開始執行的最后一個操作(然后使用一堆操作)。 撤消用戶希望的任何動作的功能要復雜得多。

要實現撤消,您需要在應用程序中創建“操作堆棧”。 但有兩種基本方法:

  1. 知道你的基線(上次保存文件,或者自文件創建以來),記住所做的每一次更改,以便在需要撤消某些內容時,只需丟棄“最頂層”項並重新生成當前項從基線查看加上所有更改。 單擊“重做”然后將該項目放回堆棧。 這樣做的另一個好處是能夠輕松地刪除堆棧中任何位置的項目而不會弄亂其他撤消/重做選項,盡管需要特別小心以確保“更高”狀態的應用程序符合用戶的意圖。

  2. 對於每個操作,存儲對先前狀態所做的更改以及在要撤消時恢復先前狀態所需的更改。 現在,當用戶點擊“撤消”時,只需執行“撤消”步驟即可。 單擊“重做”時,重新應用所做的更改。 在某些情況下,“撤消”步驟將是“這就是以前的樣子”,但如果你想讓用戶刪除不在堆棧頂部的物品然后需要移除上面的東西,那么這可能會造成嚴重破壞它。

正確的選擇取決於很多因素,包括您可以/將攜帶多少數據。 在某種意義上,選項#1更容易,但如果動作堆棧很大,則撤消任何內容都會變得很慢。

你應該檢查命令模式

另一個參考: 使用命令模式進行撤消功能

另見紀念品圖案。 有時,必須進入撤消操作的命令的智能非常復雜。 例如,在繪圖程序中繪制對象。 可以更容易地存儲紀念品,然后從該紀念品中恢復以實現撤消。

您可以存儲狀態快照。 State是操作可以修改的數據集。 單擊“撤消”時,當前狀態將替換為“上一個”。 實際上這不是一項微不足道的任務,特別是如果國家很復雜的話。

我最近一直在試驗這個問題。 如果您不需要二進制兼容性,請查看https://github.com/d-led/undoredo-cpp

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM