In this article, we will learn how to use and implement the Memento Pattern in C++ with an example.
Memento is a behavioral design pattern that lets you save and restore the previous state of an object without revealing the details of its implementation.
C++ Memento Pattern Example
The below diagram shows the generic structure of the Memento Pattern:
Let's refer to the above structure to create an example to demonstrates the usage of the Memento Pattern.
#include <iostream> #include <vector> /* * Memento * stores internal state of the Originator object and protects * against access by objects other than the originator */ class Memento { private: // accessible only to Originator friend class Originator; Memento( const int s ) : state( s ) {} void setState( const int s ) { state = s; } int getState() { return state; } // ... private: int state; // ... }; /* * Originator * creates a memento containing a snapshot of its current internal * state and uses the memento to restore its internal state */ class Originator { public: // implemented only for printing purpose void setState( const int s ) { std::cout << "Set state to " << s << "." << std::endl; state = s; } // implemented only for printing purpose int getState() { return state; } void setMemento( Memento* const m ) { state = m->getState(); } Memento *createMemento() { return new Memento( state ); } private: int state; }; /* * CareTaker * is responsible for the memento's safe keeping */ class CareTaker { public: CareTaker( Originator* const o ) : originator( o ) {} ~CareTaker() { for ( unsigned int i = 0; i < history.size(); i++ ) { delete history.at( i ); } history.clear(); } void save() { std::cout << "Save state." << std::endl; history.push_back( originator->createMemento() ); } void undo() { if ( history.empty() ) { std::cout << "Unable to undo state." << std::endl; return; } Memento *m = history.back(); originator->setMemento( m ); std::cout << "Undo state." << std::endl; history.pop_back(); delete m; } private: Originator *originator; std::vector<Memento*> history; }; int main() { Originator *originator = new Originator(); CareTaker *caretaker = new CareTaker( originator ); originator->setState( 1 ); caretaker->save(); originator->setState( 2 ); caretaker->save(); originator->setState( 3 ); caretaker->undo(); std::cout << "Actual state is " << originator->getState() << "." << std::endl; delete originator; delete caretaker; return 0; }
Output
Set state to 1.
Save state.
Set state to 2.
Save state.
Set state to 3.
Undo state.
Actual state is 2.
When to use?
- a snapshot of an object's state must be saved so that it can be restored to that state later
- a direct interface to obtaining the state would expose implementation details and break the object's encapsulation
Related C++ Design Patterns
- C++ Factory Method Pattern Example
- C++ Builder Pattern Example
- C++ Abstract Factory Pattern Example
- C++ Bridge Pattern Example
- C++ Chain of Responsibility Pattern Example
- C++ Composite Pattern Example
- C++ Decorator Pattern Example
- C++ Facade Pattern Example
- C++ Mediator Pattern Example
- C++ Memento Pattern Example
- C++ Observer Pattern Example
- C++ Proxy Pattern Example
- C++ Strategy Pattern Example
- C++ State Pattern Example
- C++ Visitor Pattern Example