2021/11/29
#include <iostream> #include <stack> #include <string> using namespace std; class Command { public: Command(){} virtual ~Command(){} virtual void Execute() = 0; }; class InputCommand : public Command { public: InputCommand( const std::string &input ) { mInput = input; } ~InputCommand() {} void Execute() { printf( "当前字符串: %s\n", mInput.c_str() ); } private: std::string mInput; }; class Commander { public: Commander( Command *pCmd ) { //最初的命令数据 mUndo.push( pCmd ); } ~Commander() { while( false == mUndo.empty() ) { delete mUndo.top(); mUndo.pop(); } while( false == mRedo.empty() ) { delete mRedo.top(); mRedo.pop(); } } void ExecuteCommand( Command *pCmd ) { pCmd->Execute(); mUndo.push( pCmd ); } void Undo() { if( mUndo.size() < 2 ) { //无法后退撤销没有数据 printf( "撤销失败.\n" ); return; } printf( "撤销:\n" ); //当前命令 auto pCmd = mUndo.top(); //保存当前命令 mRedo.push( pCmd ); //弹出 mUndo.pop(); //还原到上个命令 pCmd = mUndo.top(); pCmd->Execute(); } void Redo() { if( mRedo.empty() ) { //无法前进重做没有数据 printf( "重写失败.\n" ); return; } printf( "重写:\n" ); auto pCmd = mRedo.top(); pCmd->Execute(); mRedo.pop(); mUndo.push( pCmd ); } private: std::stack< Command* > mUndo; std::stack< Command* > mRedo; }; int main() { //默认没有输入字符串可以是空,这里为了演示赋值一个特殊的字符串 Commander *p = new Commander( new InputCommand( "[empty]" ) ); //输入1234 p->ExecuteCommand( new InputCommand( "123" ) ); //输入567 p->ExecuteCommand( new InputCommand( "567" ) ); //输入xxx p->ExecuteCommand( new InputCommand( "xxx" ) ); //执行一次undo 撤销到 567 p->Undo(); //执行一次undo 撤销到 1234 p->Undo(); //undo后中间输入新字符串 insert 覆盖 1234 p->ExecuteCommand( new InputCommand( "insert" ) ); //执行一次undo 撤销到 1234 p->Undo(); //执行一次undo 撤销到最初情况 [empty] p->Undo(); //执行失败已经undo 到最原始情况 p->Undo(); //执行一次redo 重做到 1234 p->Redo(); //执行一次redo 重做到 insert p->Redo(); //执行一次redo 重做到 567 p->Redo(); //redo后中间输入新字符串 insert again 覆盖 567 p->ExecuteCommand( new InputCommand( "insert again" ) ); //执行一次undo 撤销到567 p->Undo(); //执行一次redo 重做到 insert again p->Redo(); //执行一次redo 重做到 xxx p->Redo(); //执行失败已经redo 到最新情况 p->Redo(); delete p; return 0; }