Как я создаю “отмену” в C++?

Я должен создать функцию, которая отменяет предыдущую задачу/дополнение/изменение. Как я делаю это в Borland C++?

(Программа хранит строки текста в текстовом файле с помощью "списка". Это хранится и затем стирается, если я не использую сохранять-функцию, я создал.)

Я означал создавать функцию отмены в простом консольном приложении между прочим.

6
задан Peter Mortensen 24 November 2018 в 03:18
поделиться

5 ответов

Также см. Образец сувенира. Иногда довольно сложно задействовать интеллект, который должен войти в команду, чтобы отменить операцию. Например, рисование объектов в программе рисования. Может быть проще просто сохранить воспоминание, а затем восстановить из него, чтобы выполнить отмену.

4
ответ дан 8 December 2019 в 02:19
поделиться

Вы можете сохранять снимки состояния. Состояние - это набор данных, которые может изменять действие. При нажатии кнопки «Отменить» текущее состояние заменяется предыдущим. На самом деле это нетривиальная задача, особенно если состояние сложное.

2
ответ дан 8 December 2019 в 02:19
поделиться

Я дам еще один ответ, но мне кажется, что пока охват недостаточен.

Эта тема далеко не тривиальна, и если погуглить, то можно найти немало результатов. Многие приложения реализуют операцию "отмены", и существует множество вариантов.

Есть два паттерна проектирования, которые могут нам здесь помочь:

  • Command: это реификация действия
  • Memento: который заключается в хранении состояния (обычно подразумевает некоторую форму сериализации)

Паттерн Command активно используется в графических средах, потому что обычно есть различные способы выполнения действия. Вспомните, например, сохранить в Microsoft Word:

  • вы можете щелкнуть на значке сохранить
  • вы можете зайти в меню Файл и выбрать сохранить
  • вы используете сочетание клавиш, обычно CTRL+S

И, конечно, сохранить, вероятно, реализовано в виде сохранить как.

Преимущество шаблона Command здесь двоякое:

  • вы можете создать стек объектов
  • вы можете попросить каждый объект выполнить операцию undo

Теперь, есть различные вопросы, связанные с undo:

  • некоторые операции нельзя отменить (например, rm в Linux или действие empty trash bin в Windows)
  • некоторые операции трудно отменить, или это может быть неестественно (вам нужно сохранить некоторое состояние, объект обычно уничтожается, но здесь вам нужно сохранить его в команде для отмены действия)
  • обычно мы думаем об отмене/повторном действии как о стеке, некоторые программы (в основном графические) предлагают отменить элементы без фактической отмены того, что было сделано после этого, этого гораздо труднее достичь, особенно когда новые действия были построены поверх того, что было отменено. ..

Поскольку существуют различные проблемы, существуют и различные стратегии:

  • Для простой команды можно рассмотреть возможность реализации отмены (например, добавление символа может быть отменено его удалением)
  • Для более сложной команды можно рассмотреть возможность реализации отмены как восстановления предыдущего состояния (вот где Memento срабатывает)
  • Если у вас много сложных команд, это может означать много Mementoов, которые потребляют место, тогда вы можете использовать подход, который заключается в запоминании только одного Snapshot каждые 10 или 20 команд, а затем повторном выполнении команд от последнего снимка до отмененной команды

На самом деле, вы можете смешивать Command и Memento на досуге, в зависимости от специфики вашей системы и, следовательно, сложности того или другого.

Я бы рассматривал возможность отмены только последнего выполненного действия для начала (используя стек действий). Функциональность отмены любого действия по желанию пользователя гораздо сложнее.

16
ответ дан 8 December 2019 в 02:19
поделиться
5
ответ дан 8 December 2019 в 02:19
поделиться

Чтобы реализовать Undo, вам нужно создать "стек действий" в вашем приложении. Есть два основных подхода:

  1. Зная базовую линию (последний раз, когда файл был сохранен, или с момента создания файла), запомните все изменения, которые были сделаны, так что когда что-то нужно отменить, вы просто отбрасываете "самый верхний" элемент и регенерируете текущий вид из базовой линии плюс все изменения. Нажав "Повторить", вы просто вернете этот элемент обратно в стек. Побочным преимуществом этого способа является возможность тривиально удалять элементы в любом месте стека, не испортив другие опции отмены/повтора, хотя потребуется особая осторожность, чтобы убедиться, что применение "высших" состояний соответствует замыслу пользователя.

  2. Для каждого действия сохраняйте изменение, которое было сделано в предыдущем состоянии, а также изменение, которое потребуется для восстановления предыдущего состояния, если отменить действие. Теперь, когда пользователь нажимает кнопку "Отменить", просто выполните действия "отмены". При нажатии "Redo", повторно примените сделанные изменения. В некоторых случаях шаги "Отменить" будут выглядеть так: "Вот как эта вещь выглядела раньше", но это может привести к хаосу, если вы хотите позволить пользователям удалять элементы, которые не находятся на вершине стопки, а затем нужно удалить что-то выше.

Правильный выбор зависит от множества факторов, включая то, сколько данных вы можете/хотите носить с собой. Вариант №1 в некотором смысле проще, но при большом стеке действий отмена действий может стать очень медленной.

13
ответ дан 8 December 2019 в 02:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: