跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

C++ 备忘录模式实战:对象状态保存与恢复

备忘录模式用于在不破坏封装性的前提下捕获对象内部状态,通过发起人、备忘录和管理者三个角色协作,实现撤销、历史记录或快照功能。C++ 实现需注意内存管理与指针生命周期,结合友元机制保护状态细节。该模式适用于文本编辑器、游戏存档及配置管理等场景,配合命令模式可构建更完善的回滚系统。

www发布于 2026/3/30更新于 2026/10/2490 浏览
C++ 备忘录模式实战:对象状态保存与恢复

C++ 备忘录模式实战:对象状态保存与恢复

在开发过程中,我们常会遇到需要撤销操作、历史记录或状态回滚的场景。备忘录模式(Memento Pattern)正是解决这类问题的经典方案。它允许在不破坏封装性的前提下,捕获并外部化对象的内部状态,以便后续恢复。

核心角色解析

实现备忘录模式主要涉及三个角色,理解它们的职责是上手的关键。

1. Originator(发起人)

这是需要保存状态的对象。它负责创建备忘录并记录当前状态,同时也能利用备忘录恢复到之前的状态。简单来说,它是状态的拥有者。

2. Memento(备忘录)

这是存储状态的容器。它有两个接口:宽接口供 Originator 使用以存取数据,窄接口供其他对象使用仅用于读取。这种设计确保了状态细节的封装性不被破坏。

3. Caretaker(管理者)

负责管理备忘录对象,比如保存列表。关键点在于,Caretaker 不操作备忘录内容,只能通过窄接口交互,避免越权访问。

设计原则体现

这个模式很好地体现了几个面向对象原则:

  • 单一职责:将状态保存从业务逻辑中剥离,Originator 更专注核心功能。
  • 开闭原则:扩展保存功能无需修改 Originator,新增备忘录类即可。
  • 迪米特法则:Caretaker 不直接触碰 Memento 内部细节,降低耦合。

C++ 实现示例

下面是一个完整的 C++ 实现。注意这里使用了友元机制来保证 Memento 对 Originator 的可见性,同时通过窄接口限制外部访问。

#include <iostream>
#include <string>
#include <vector>

// 备忘录类
class Memento {
private:
    std::string state;
    // 只有 Originator 可以访问私有成员
    friend class Originator;
    
    Memento(const std::string& s) : state(s) {}
    std::string GetState() const { return state; }
};

// 发起人类
class Originator {
private:
    std::string state;
public:
    void SetState(const std::string& s) {
        std::cout << "设置状态:" << s << std::endl;
        state = s;
    }
    
    Memento* CreateMemento() {
        return new Memento(state);
    }
    
    void RestoreFromMemento(const Memento* m) {
        state = m->GetState();
        std::cout << "恢复状态:" << state << std::endl;
    }
};

// 管理者类
class Caretaker {
private:
    std::vector<Memento*> mementos;
    Originator* originator;
public:
    Caretaker(Originator* orig) : originator(orig) {}
    
    ~Caretaker() {
        for (auto m : mementos) delete m;
    }
    
    void Save() {
        mementos.push_back(originator->CreateMemento());
    }
    
    void Undo() {
        if (mementos.empty()) return;
        Memento* m = mementos.back();
        originator->RestoreFromMemento(m);
        mementos.pop_back();
        delete m;
    }
};

// 使用示例
int main() {
    Originator originator;
    Caretaker caretaker(&originator);
    
    originator.SetState("状态 1");
    caretaker.Save();
    
    originator.SetState("状态 2");
    caretaker.Save();
    
    originator.SetState("状态 3");
    
    // 执行撤销,恢复到状态 2
    caretaker.Undo();
    // 再次撤销,恢复到状态 1
    caretaker.Undo();
    
    return 0;
}

在实际工程中,考虑到内存安全,建议配合智能指针使用,或者在析构函数中确保资源释放,避免内存泄漏。

典型应用场景

备忘录模式适合以下场景:

  1. 撤销/重做功能:如文本编辑器的 Ctrl+Z。
  2. 事务回滚系统:数据库操作失败时恢复现场。
  3. 游戏存档系统:保存进度快照。
  4. 配置管理:保留配置的历史版本。

高级特性与优化

1. 增量备忘录

如果状态变化不大,只保存差异部分能显著减少内存消耗。

2. 序列化支持

通过序列化技术,可以将备忘录持久化到文件或数据库,实现跨会话的状态恢复。

3. 线程安全考虑

多线程环境下使用时,需添加锁机制保证状态一致性。

与其他模式的协作

备忘录模式常与其他模式配合:

  • 命令模式:结合实现可撤销的操作栈。
  • 原型模式:通过克隆优化备忘录创建过程。
  • 状态模式:保存不同状态配置。

注意事项

  1. 内存消耗:大对象频繁保存可能导致内存压力,需评估频率和大小。
  2. C++ 内存管理:手动管理指针时需格外小心,推荐使用 RAII 机制。
  3. 替代方案:对于简单对象,原型模式可能更轻量。

总结

备忘录模式通过状态封装实现了灵活的回滚机制,是提升系统可维护性和扩展性的有效手段。在 C++ 中实现时,重点在于平衡封装性与内存安全。掌握这一模式,能让你的代码在处理历史状态时更加稳健。

目录

  1. C++ 备忘录模式实战:对象状态保存与恢复
  2. 核心角色解析
  3. 1. Originator(发起人)
  4. 2. Memento(备忘录)
  5. 3. Caretaker(管理者)
  6. 设计原则体现
  7. C++ 实现示例
  8. 典型应用场景
  9. 高级特性与优化
  10. 1. 增量备忘录
  11. 2. 序列化支持
  12. 3. 线程安全考虑
  13. 与其他模式的协作
  14. 注意事项
  15. 总结

更多推荐文章

查看全部
  • OpenClaw 龙虾机器人本地部署与配置指南
  • C++ STL list 容器底层实现分析
  • 使用 OpenClaw 与飞书构建 7x24 小时自动化运维机器人
  • 职场人士如何自学 Python:目标规划与学习路径
  • 基于 SpringBoot 的图书租借系统设计与实现
  • 声源定位算法基础:CBF(延时求和波束形成)
  • QA 一来,大家都要靠边站
  • Java 集成 Umi-OCR 实现本地图片文字提取
  • LangChain 实战:基于网页数据的 RAG 问答及来源溯源
  • Google 秘密计划曝光:AI 或取代人类程序员敲代码
  • 医疗 AI 场景下的模型融合与集成策略实战
  • 医疗 AI 多智能体资源调度:用 Python 构建 MCU 资源池
  • OpenClaw 深度解析:构建从认知到行动的 AI 智能体框架
  • Windows 11 资源管理器增强工具 QTTabBar 中文优化版安装指南
  • AIGC 核心技术解析:生成对抗网络(GAN)应用与原理
  • VS Code GitHub Copilot 登录报错“尚未完成授权”解决方案
  • Spring Boot 集成本地 OCR 服务模块实战
  • Verilog 零基础入门:语法、仿真与 FPGA 实战
  • 基于 MP-GWO 灰狼优化算法的多智能体无人机航迹规划
  • 程序员接外包私活平台推荐:主流接单网站盘点与避坑指南

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online