C++与设计模式(12)——备忘录模式

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态

这里以棋子坐标为例,通过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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值