Я должен создать функцию, которая отменяет предыдущую задачу/дополнение/изменение. Как я делаю это в Borland C++?
(Программа хранит строки текста в текстовом файле с помощью "списка". Это хранится и затем стирается, если я не использую сохранять-функцию, я создал.)
Я означал создавать функцию отмены в простом консольном приложении между прочим.
Также см. Образец сувенира. Иногда довольно сложно задействовать интеллект, который должен войти в команду, чтобы отменить операцию. Например, рисование объектов в программе рисования. Может быть проще просто сохранить воспоминание, а затем восстановить из него, чтобы выполнить отмену.
Вы можете сохранять снимки состояния. Состояние - это набор данных, которые может изменять действие. При нажатии кнопки «Отменить» текущее состояние заменяется предыдущим. На самом деле это нетривиальная задача, особенно если состояние сложное.
Я дам еще один ответ, но мне кажется, что пока охват недостаточен.
Эта тема далеко не тривиальна, и если погуглить, то можно найти немало результатов. Многие приложения реализуют операцию "отмены", и существует множество вариантов.
Есть два паттерна проектирования, которые могут нам здесь помочь:
Command
: это реификация действияMemento
: который заключается в хранении состояния (обычно подразумевает некоторую форму сериализации)Паттерн Command
активно используется в графических средах, потому что обычно есть различные способы выполнения действия. Вспомните, например, сохранить в Microsoft Word:
И, конечно, сохранить, вероятно, реализовано в виде сохранить как.
Преимущество шаблона Command
здесь двоякое:
undo
Теперь, есть различные вопросы, связанные с undo
:
rm
в Linux или действие empty trash bin в Windows)Поскольку существуют различные проблемы, существуют и различные стратегии:
Memento
срабатывает)Memento
ов, которые потребляют место, тогда вы можете использовать подход, который заключается в запоминании только одного Snapshot каждые 10 или 20 команд, а затем повторном выполнении команд от последнего снимка до отмененной командыНа самом деле, вы можете смешивать Command
и Memento
на досуге, в зависимости от специфики вашей системы и, следовательно, сложности того или другого.
Я бы рассматривал возможность отмены только последнего выполненного действия для начала (используя стек действий). Функциональность отмены любого действия по желанию пользователя гораздо сложнее.
Вам следует ознакомиться с Командным шаблоном .
Другая ссылка: Использование шаблона команд для отмены действия
Чтобы реализовать Undo, вам нужно создать "стек действий" в вашем приложении. Есть два основных подхода:
Зная базовую линию (последний раз, когда файл был сохранен, или с момента создания файла), запомните все изменения, которые были сделаны, так что когда что-то нужно отменить, вы просто отбрасываете "самый верхний" элемент и регенерируете текущий вид из базовой линии плюс все изменения. Нажав "Повторить", вы просто вернете этот элемент обратно в стек. Побочным преимуществом этого способа является возможность тривиально удалять элементы в любом месте стека, не испортив другие опции отмены/повтора, хотя потребуется особая осторожность, чтобы убедиться, что применение "высших" состояний соответствует замыслу пользователя.
Для каждого действия сохраняйте изменение, которое было сделано в предыдущем состоянии, а также изменение, которое потребуется для восстановления предыдущего состояния, если отменить действие. Теперь, когда пользователь нажимает кнопку "Отменить", просто выполните действия "отмены". При нажатии "Redo", повторно примените сделанные изменения. В некоторых случаях шаги "Отменить" будут выглядеть так: "Вот как эта вещь выглядела раньше", но это может привести к хаосу, если вы хотите позволить пользователям удалять элементы, которые не находятся на вершине стопки, а затем нужно удалить что-то выше.
Правильный выбор зависит от множества факторов, включая то, сколько данных вы можете/хотите носить с собой. Вариант №1 в некотором смысле проще, но при большом стеке действий отмена действий может стать очень медленной.