#pragma once

#ifndef MEMENTO_H

#define MEMENTO_H

#include <string>

typedef std::string State;

class Memento;

class Originator
{
public:
Originator(const State& rState);
Originator();
~Originator();
Memento* CreateMemento();
void SetMemento(Memento* pMemento);
State GetState();
void SetState(const State& rState);
void RestoreState(Memento* pMemento);
void PrintState();

private:
State m_State;
};

// 把Memento 的接口函数都设置为私有的,而Originator 是它的友元,
// 这样保证了只有Originator 可以对其访问
class Memento
{
private:
friend class Originator;
Memento(const State& rState);
void SetState(const State& rState);
State GetState();
State m_State;
};

#endif


#include "StdAfx.h"
#include "memento_impl.h"

#include <iostream>

Originator::Originator()
{
}

Originator::Originator(const State& rState)
: m_State(rState)
{
}

Originator::~Originator()
{
}

State Originator::GetState()
{
return m_State;
}

void Originator::SetState(const State& rState)
{
m_State = rState;
}

Memento* Originator::CreateMemento()
{
return new Memento(m_State);
}

void Originator::RestoreState(Memento* pMemento)
{
if (NULL != pMemento)
{
m_State = pMemento->GetState();
}
}

void Originator::PrintState()
{
std::cout << "State = " << m_State << std::endl;
}

Memento::Memento(const State& rState)
: m_State(rState)
{
}

State Memento::GetState()
{
return m_State;
}

void Memento::SetState(const State& rState)
{
m_State = rState;
}


// Memento.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include "memento_impl.h"
#include <stdlib.h>
//在不破坏封装性的前提下,捕获一个对象的内部状态,
//并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态.
int _tmain(int argc, _TCHAR* argv[])
{
// 创建一个原发器
Originator* pOriginator = new Originator("old state");
pOriginator->PrintState();

// 创建一个备忘录存放这个原发器的状态
Memento *pMemento = pOriginator->CreateMemento();

// 更改原发器的状态
pOriginator->SetState("new state");

pOriginator->PrintState();
// 通过备忘录把原发器的状态还原到之前的状态
pOriginator->RestoreState(pMemento);

pOriginator->PrintState();

delete pOriginator;
delete pMemento;
system("pause");

return 0;
}