2010-04-30 42 views
6

Tengo un par de códigos para hacer algunas cosas, pero necesito crear una función que deshaga la tarea/adición/cambio anterior. ¿Cómo hago esto en Borland C++?¿Cómo creo "deshacer" en C++?

(el programa almacena cadenas de texto en un archivo de texto usando "lista", se almacena y después se pueden borrar a menos que utilice la función de guardar He creado)

derecha, por lo que no saben si he olvidado mencionar algo de importancia para que pueda ayudarme mejor, pero si hay algo que se pregunta acerca de las funciones solo pregunte.

Me refiero a crear una función de deshacer en una simple aplicación de consol por cierto.

Respuesta

2

puede almacenar instantáneas de estado. estado es un conjunto de datos que la acción puede modificar. cuando haces clic en deshacer el estado actual es reemplazado por el anterior. en realidad no es una tarea trivial, especialmente si el estado es complejo.

4

También vea el patrón de recuerdo. A veces, la inteligencia que debe entrar en un comando para deshacer una operación es bastante complicada. Dibujar objetos en un programa de pintura, por ejemplo. Puede ser más fácil simplemente almacenar un recuerdo y luego restaurar desde ese recuerdo para implementar deshacer.

13

Para implementar Deshacer, necesita crear una "pila de acciones" en su aplicación. Hay dos enfoques básicos, sin embargo:

  1. Conocer su línea de base (la última vez que se guardó el archivo, o desde que se creó el archivo), recuerda cada cambio único que se hizo para que cuando algo necesita ser deshecho simplemente descarta el ítem "más alto" y regenera la vista actual desde la línea base más todos los cambios. Al hacer clic en "Rehacer", simplemente vuelve a colocar ese elemento en la pila. Esto tiene el beneficio adicional de poder eliminar elementos en cualquier lugar de la pila sin arruinar otras opciones de deshacer/rehacer, aunque habrá que tener especial cuidado para asegurarse de que la aplicación de estados "superiores" sea la deseada por el usuario.

  2. Para cada acción, almacene el cambio que se hizo en el estado anterior así como el cambio que sería necesario para restaurar ese estado anterior si tuviera que deshacer. Ahora cuando el usuario hace clic en "Deshacer", simplemente haga los pasos "deshacer". Al hacer clic en "Rehacer", vuelva a aplicar los cambios que se realizaron. En algunos casos, los pasos de "Deshacer" serán "así es como se veía antes", pero eso puede causar estragos si desea permitir que los usuarios eliminen elementos que no están en la parte superior de la pila y luego deben quitar algo arriba. eso.

La elección correcta depende de muchos factores, incluida la cantidad de datos que puede/llevará. La opción n. ° 1 es, en cierto sentido, más fácil, pero podría deshacerse lentamente si la pila de acción es grande.

+0

Parece que te han vencido en este, pero me gusta tu línea de pensamiento. Especialmente eres el único que consideró el problema de querer deshacer algo que no está en la parte superior de la pila, ¡lo cual no es trivial! –

+0

Gracias, y sí, las otras respuestas apuntaban a patrones, pero en realidad no los discutían. Eso está muy bien, pero no soy un gran fanático de intentar adaptar los patrones a los problemas como punto de partida. Usualmente (para mí, usando TDD) funciona de la otra manera; un patrón se revela una vez que se alcanza la solución. –

16

Daré una respuesta más, pero creo que la cobertura ha sido insuficiente hasta el momento.

El tema está lejos de ser trivial, y Google devuelve una buena cantidad de resultados. Muchas aplicaciones implementan una operación de "deshacer" y hay muchas variantes.

Hay 2 patrones de diseño que nos puede ayudar aquí:

  • Command: es una cosificación de una acción
  • Memento: que consiste en el almacenamiento de estado (por lo general implica algún tipo de serialización)

El patrón Command se usa mucho en entornos gráficos porque generalmente hay varias formas de realizar una acción. Piense en Guardar en Microsoft Word por ejemplo:

  • puede hacer clic en el icono Guardar
  • se puede entrar en Archivo menú y haga clic en Guardar
  • utiliza el método abreviado , normalmente CTRL + S

Y, por supuesto Guardar probablemente se implemente en el término de , guarde como.

La ventaja del patrón Command aquí es doble:

  • puede crear una pila de objetos
  • puede pedir a cada objeto de implementar una operación undo

Ahora, hay varios problemas propios de undo:

  • algunas operaciones no se pueden deshacer (por ejemplo, considere rm en Linux o el Vaciar la papelera acción en Windows)
  • algunas operaciones son difíciles de deshacer, o puede no ser natural (que necesita para almacenar algún estado, el objeto normalmente se destruye pero aquí necesitaría almacenarlo dentro del comando para la acción de deshacer)
  • generalmente pensamos en deshacer/rehacer como una pila, algunos programas (principalmente gráficos) proponen deshacer los artículos sin deshacer realmente lo que se ha perdido hecho después, esto es mucho más difícil de lograr, especialmente cuando las acciones más nuevas se han construido sobre la de deshacer ...

Debido a que hay varios problemas, hay varias estrategias:

  • Para un simple comando, usted podría considerar la implementación de un deshacer (por ejemplo, añadiendo un carácter se puede deshacer quitándolo)
  • Para un comando más complejo, puede considerar implementar deshacer como restaurar el estado anterior (ahí es donde Memento se activan)
  • Si tiene muchos Comandos complejos, eso podría significar muchos Memento que consumen espacio, entonces puede nos e un enfoque que consiste solamente en memorizar una instantánea cada 10 o 20 comandos, y luego volver a hacer los comandos desde la última instantánea hasta el comando deshacer

De hecho, es probable que pueda mezclar Command y Memento en el ocio , dependiendo de los detalles de su sistema y, por lo tanto, de la complejidad de ambos.

Solo me gustaría deshacer la última acción ejecutada para empezar (usando una pila de acciones). La funcionalidad de deshacer cualquier acción que el usuario desee es mucho más complicada.