- C++ Home
- C++ Overview
- C++ Environment Setup
- C++ Basic Syntax
- C++ Comments
- C++ Hello World
- C++ Omitting Namespace
- C++ Tokens
- C++ Constants/Literals
- C++ Keywords
- C++ Identifiers
- C++ Data Types
- C++ Numeric Data Types
- C++ Character Data Type
- C++ Boolean Data Type
- C++ Variable Types
- C++ Variable Scope
- C++ Multiple Variables
- C++ Input Output Operations
- C++ Basic Input/Output
- C++ Cin
- C++ Cout
- C++ Manipulators
- Type System & Data Representation
- C++ Modifier Types
- C++ Storage Classes
- C++ Constexpr Specifier
- C++ Numbers
- C++ Enumeration
- C++ Enum Class
- C++ References
- C++ Date & Time
- C++ Operators
- C++ Operators
- C++ Arithmetic Operators
- C++ Relational Operators
- C++ Logical Operators
- C++ Bitwise Operators
- C++ Assignment Operators
- C++ sizeof Operator
- C++ Conditional Operator
- C++ Comma Operator
- C++ Member Operators
- C++ Casting Operators
- C++ Pointer Operators
- C++ Operators Precedence
- C++ Unary Operators
- C++ Scope Resolution Operator
- C++ Control Statements
- C++ Decision Making
- C++ if Statement
- C++ if else Statement
- C++ Nested if Statements
- C++ switch Statement
- C++ Nested switch Statements
- C++ Loop Types
- C++ while Loop
- C++ for Loop
- C++ do while Loop
- C++ Foreach Loop
- C++ Nested Loops
- C++ Jump Statements
- C++ break Statement
- C++ continue Statement
- C++ goto Statement
- C++ Return Values
- C++ Strings
- C++ Strings
- C++ Loop Through a String
- C++ String Length
- C++ String Concatenation
- C++ String Comparison
- C++ Functions
- C++ Functions
- C++ Multiple Function Parameters
- C++ Recursive Function
- C++ Function Overloading
- C++ Function Overriding
- C++ Default Arguments
- C++ Arrays
- C++ Arrays
- C++ Multidimensional Arrays
- C++ Pointer to an Array
- C++ Passing Arrays to Functions
- C++ Return Array from Functions
- C++ Array Decay
- C++ Structure & Union
- C++ Structures
- C++ Unions
- C++ Class and Objects
- C++ Object Oriented
- C++ Classes & Objects
- C++ Class Member Functions
- C++ Class Access Modifiers
- C++ Static Class Members
- C++ Static Data Members
- C++ Static Member Function
- C++ Inline Functions
- C++ this Pointer
- C++ Friend Functions
- C++ Pointer to Classes
- C++ Constructors
- C++ Constructor & Destructor
- C++ Default Constructors
- C++ Parameterized Constructors
- C++ Copy Constructor
- C++ Constructor Overloading
- C++ Constructor with Default Arguments
- C++ Delegating Constructors
- C++ Constructor Initialization List
- C++ Dynamic Initialization Using Constructors
- C++ Destructors
- C++ Virtual Destructor
- C++ Inheritance
- C++ Inheritance
- C++ Multiple Inheritance
- C++ Multilevel Inheritance
- C++ Object-oriented
- C++ Overloading
- C++ Polymorphism
- C++ Abstraction
- C++ Encapsulation
- C++ Interfaces
- C++ Virtual Function
- C++ Pure Virtual Functions & Abstract Classes
- C++ Override Specifiers
- C++ Final Specifiers
- C++ Design Patterns
- C++ Creational Design Patterns
- C++ Singleton Design Pattern
- C++ Factory Method Design Pattern
- C++ Abstract Factory Pattern
- C++ Prototype Design Pattern
- C++ Structural Design Patterns
- C++ Facade Design Pattern
- C++ Iterator Design Pattern
- C++ Mediator Design Pattern
- C++ Memento Design Pattern
- C++ Observer Design Pattern
- C++ State Design Pattern
- C++ File Handling
- C++ Files and Streams
- C++ Reading From File
- C++ Advanced
- C++ Exception Handling
- C++ Dynamic Memory
- C++ Move Semantics
- C++ Namespaces
- C++ Templates
- C++ Preprocessor
- C++ Signal Handling
- C++ Multithreading
- C++ Web Programming
- C++ Socket Programming
- C++ Concurrency
- C++ Advanced Concepts
- C++ Lambda Expression
- C++ nullptr
- C++ unordered_multiset
- C++ Chain of Responsibility
- C++ Structural Design Patterns
- C++ Adapter Pattern
- C++ Bridge Pattern
- C++ Composite Pattern
- C++ Decorator Pattern
- C++ Flyweight Pattern
- C++ Command Pattern
- C++ Proxy Pattern
Memento Design Pattern in C++
Memento Design Pattern is a behavioral design pattern that allows an object to capture its internal state and save it externally so that it can be restored later without violating encapsulation. This pattern is particularly useful when you want to implement features like undo/redo functionality in applications.
For example, take an application where users can edit documents. By using the Memento Design Pattern, the application can save the state of the document at various points in time. If the user wants to undo their last action, the application can restore the document to its previous state using the saved memento. This way, the internal state of the document is preserved without exposing its details to other parts of the application.
Components of Memento Design Pattern
The Memento Design Pattern consists of three main components −
- Originator − The main object you want to save and restore. It can make a memento (a snapshot of its current state) and later use that memento to go back to how it was before. For example, in a text editor, the Originator is the editor itself that holds your text.
- Memento − A special object that remembers the state of the Originator at a certain time. Once made, its contents cannot be changed, so you can always trust it to bring things back exactly as they were. Think of it like a bookmark or a save point.
- Caretaker − The helper that keeps track of all the mementos (saved states). It stores them safely and can ask the Originator to go back to a previous state when needed. The Caretaker never looks inside the mementos or changes them; it just holds onto them and gives them back when you want to undo or redo something.
C++ Implementation of Memento Design Pattern
We will use all three components of the Memento Design Pattern to implement a simple text editor that allows users to type text and undo their last action.
In this editor, the Originator will be the TextEditor class, which maintains the current text and creates mementos to save its state. The Memento will be the TextMemento class, which stores the text state. The Caretaker will be the EditorHistory class, which manages the mementos and allows undo functionality.
Steps to Implement Memento Design Pattern in C++
Follow these steps to implement the Memento Design Pattern in C++
- Create a Memento class ( TextMemento ) that will save the from the editor. This class just keeps a copy of the text so you can get it back later.
- Make an Originator class ( TextEditor ). This is your main editor where you type and change text. It can create a memento to save its current text, and it can restore its text from a memento if you want to go back.
- Add a Caretaker class ( EditorHistory ). This class remembers all the saved versions (mementos) of your text. It lets you undo by giving you back the last saved version.
- Write a main function to show how it works. Here, you will type some text, save it, and then use undo to go back to earlier versions.
C++ Code of Memento Design Pattern
Below is the C++ code that implements the Memento Design Pattern for a simple text editor with undo functionality −
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// Memento class
class TextMemento {
private:
string textState;
public:
TextMemento(const string &state) : textState(state) {}
string getState() const { return textState; }
};
// Originator class
class TextEditor {
private:
string text;
public:
void type(const string &newText) {
text += newText;
}
string getText() const {
return text;
}
TextMemento save() {
return TextMemento(text);
}
void restore(const TextMemento &memento) {
text = memento.getState();
}
};
// Caretaker class
class EditorHistory {
private:
vector<TextMemento> history;
public:
void push(const TextMemento &memento) {
history.push_back(memento);
}
TextMemento pop() {
if (!history.empty()) {
TextMemento memento = history.back();
history.pop_back();
return memento;
}
return TextMemento("");
}
};
// Main function to demonstrate Memento Design Pattern
int main() {
TextEditor editor;
EditorHistory history;
editor.type("Hello, ");
history.push(editor.save());
editor.type("World!");
history.push(editor.save());
cout << "Current Text: " << editor.getText() << endl;
editor.restore(history.pop());
cout << "After Undo: " << editor.getText() << endl;
editor.restore(history.pop());
cout << "After Undo: " << editor.getText() << endl;
return 0;
}
In this code, we have defined the TextMemento class to store the text state, the TextEditor class to manage the text and create/restore mementos, and the EditorHistory class to manage the history of mementos for undo functionality. The main function demonstrates how to use these classes to type text and undo actions.
Current Text: Hello, World! After Undo: Hello, After Undo:
Pros and Cons of Memento Design Pattern
Following are the advantages and disadvantages of using the Memento Design Pattern −
| Pros | Cons |
|---|---|
| Undo is easy and helpful. You can quickly go back to an earlier version if you make a mistake or want to change something. | It can use a lot of memory if you keep saving many versions. This might make your program slower or take up more space. |
| Your object's details stay safe. Other parts of your program cannot change or see the inside details by mistake, so your data is protected. | You need to make extra classes to use this pattern. This can make your code a little more complicated and harder to manage. |
| Undo and redo features are simple to add. This pattern makes it easy for users to fix mistakes or try different things without worry. | Saving big or many states can slow things down. If your program saves a lot of information often, it might not run as fast. |
When to Use Memento Design Pattern
The Memento Design Pattern is very useful in everyday programs where you want to let people fix mistakes or go back to something they did before. It is especially helpful for adding undo and redo features, which make programs much easier and safer to use.
For example, if someone is writing in a text editor or drawing in a paint app, they might make a mistake. With this pattern, the program can save the state of their work at different times. If they want to fix a mistake, they can restore an earlier version without anyone seeing or changing the private details inside the program.
This pattern is also great for keeping a history of changes. People can easily go back to an earlier version of their work if they change their mind or want to try something different. It helps make programs more friendly and less stressful to use.
Real-World Examples of Memento Design Pattern
Here are some real-world examples where the Memento Design Pattern is used in simple, everyday language −
- Text editors like Notepad or Word let you undo and redo what you type. If you make a mistake, you can easily go back to how it was before.
- Drawing or graphic design apps let you revert to an earlier version of your picture. If you don't like your last change, you can bring back the old version.
- Video games often let you save your progress. If you lose or want to try again, you can load your saved game and start from there.
- Version control systems (like Git) help you track changes to your files. If you want to go back to an older version, you can restore it easily.
- Databases use this pattern to roll back to a safe state if something goes wrong, so your data stays safe.
- Settings or configuration managers let you save your system settings. If you change something and it doesn't work, you can restore the old settings.
Conclusion
In this chapter, you learned about the Memento Design Pattern, its three main parts, and how to use it in C++. You also saw the good and bad sides, when to use it, and some real-life examples. The Memento Pattern is a great way to let users undo and redo actions, keep their data safe, and make your programs easier to use.