备忘录模式通过Originator、Memento、Caretaker三类角色实现对象状态的保存与恢复:Originator创建/恢复状态并声明Memento为友元;Memento封装只读快照;Caretaker以黑盒方式管理备忘录集合。

备忘录模式(Memento Pattern)用于在不破坏封装性的前提下,捕获并外部化一个对象的内部状态,以便之后可以恢复到该状态。C++ 中实现该模式需明确三类角色:发起人(Originator)、备忘录(Memento)、管理者(Caretaker)。
Originator:负责创建和恢复状态
发起人持有需要保存/恢复的核心数据,提供 save() 创建备忘录、restore(Memento) 恢复状态的方法。关键点是备忘录类应为 Originator 的友元,或通过公有接口隔离内部细节——推荐用友元方式保证封装性,同时允许安全访问私有成员。
示例:
class Originator {
private:
std::string state;
public:
Originator(const std::string& s) : state(s) {}
void setState(const std::string& s) { state = s; }
std::string getState() const { return state; }
// 创建备忘录:返回一个包含当前状态的 Memento 对象
Memento save() const { return Memento(state); }
// 从备忘录恢复状态
void restore(const Memento& m) { state = m.getState(); }};
立即学习“C++免费学习笔记(深入)”;
Memento:只读快照,封装内部状态
备忘录对象仅用于存储快照,对外不提供修改接口。它通常将状态设为私有,并只允许 Originator 访问(通过 friend 声明)。避免暴露 setter 或直接访问字段,防止外部篡改历史状态。
示例:
class Memento {
private:
std::string state;
public:
explicit Memento(const std::string& s) : state(s) {}
// 只提供只读访问
std::string getState() const { return state; }
// 关键:声明 Originator 为友元,允许其读写私有 state
friend class Originator;};
立即学习“C++免费学习笔记(深入)”;
Caretaker:管理多个备忘录,不窥探内容
管理者负责保存、索引、按需提供备忘录,但它不能访问或修改备忘录内部数据。它只把 Memento 当作黑盒处理。常见做法是用 vector 或 stack 存储备忘录,支持撤销(undo)或重做(redo)逻辑。
示例:
class Caretaker {
private:
std::vector history;
public:
void addMemento(const Memento& m) {
history.push_back(m);
}
Memento getMemento(size_t index) const {
if (index < history.size()) {
return history[index];
}
throw std::out_of_range("Invalid memento index");
}
size_t size() const { return history.size(); }};
立即学习“C++免费学习笔记(深入)”;
完整使用示例
组合三者,模拟编辑器文本状态的保存与回滚:
int main() {
Originator editor("Initial content");
Caretaker history;
std::cout << "Current: " << editor.getState() << "\n";
history.addMemento(editor.save()); // 保存初始状态
editor.setState("After first edit");
std::cout << "Edited: " << editor.getState() << "\n";
history.addMemento(editor.save()); // 保存编辑后状态
editor.setState("After second edit");
std::cout << "Edited again: " << editor.getState() << "\n";
// 撤销:恢复到上一个备忘录
editor.restore(history.getMemento(history.size() - 2));
std::cout << "Restored: " << editor.getState() << "\n"; // 输出 "After first edit"}
注意:若需支持多次撤销,可配合栈结构(std::stack











