在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态
这里以棋子坐标为例,通过ChessMemento来保存ChessMan的信息,并通过ChessCaretaker进行管理来实现悔棋和撤销等操作。
class ChessMemento
{
public:
ChessMemento():m_x(0),m_y(0),m_str(""){}
ChessMemento(int x,int y,string str):m_x(x),m_y(y),m_str(str){}
ChessMemento& operator=(const ChessMemento &memento)
{
m_x = memento.m_x;
m_y = memento.m_y;
m_str = memento.m_str;
return *this;
}
public:
int m_x;
int m_y;
string m_str;
};
class ChessMan
{
public:
ChessMan(int x,int y,string str):m_x(x),m_y(y),m_str(str){}
void show(){cout << m_str <<" in " << m_x << "," << m_y <<endl;}
ChessMemento save(){return ChessMemento(m_x,m_y,m_str);}
void restore(const ChessMemento* e)
{
if(e != 0)
{
m_x = e->m_x;
m_y = e->m_y;
m_str = e->m_str;
}
}
public:
int m_x;
int m_y;
string m_str;
};
class ChessCaretaker
{
public:
ChessCaretaker():flag(0){}
void save(ChessMemento menento)
{
if(flag != 0)
{
m_vecMemento.resize(m_vecMemento.size() - flag);
flag = 0;
}
m_vecMemento.push_back(menento);
}
const ChessMemento* undo()
{
if(m_vecMemento.size() < flag + 2)
{
cout << "This is first number" << endl;
return 0;
}
return &m_vecMemento[m_vecMemento.size() - (++flag) - 1];
}
const ChessMemento* redo()
{
if(flag == 0)
{
cout << "This is last number" << endl;
return 0;
}
return &m_vecMemento[m_vecMemento.size() - (--flag) - 1];
}
private:
vector<ChessMemento> m_vecMemento;
int flag;
};
int main()
{
ChessCaretaker caretaker;
ChessMan chessman(1,1,"chess1");//初始为(1,1)
chessman.show();
caretaker.save(chessman.save());
chessman.m_x = 2;//(2,1)
chessman.show();
caretaker.save(chessman.save());
chessman.m_y = 3;//(2,3)
chessman.show();
caretaker.save(chessman.save());
chessman.m_y = 3000;//(2,3000)
chessman.show();
caretaker.save(chessman.save());
chessman.restore(caretaker.undo());//悔棋至(2,3)
chessman.show();
chessman.restore(caretaker.undo());//悔棋至(2,1)
chessman.show();
chessman.restore(caretaker.undo());//悔棋至(1,1)
chessman.show();
chessman.restore(caretaker.redo());//撤销至(2,1)
chessman.show();
chessman.m_y = 4;//(2,4),覆盖(2,3)的记录
chessman.show();
caretaker.save(chessman.save());
return 0;
}