展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > C++备忘录模式实现:对象状态保存与恢复方法

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

在C++中使用备忘录模式是为了在不破坏对象封装性的前提下实现状态的保存与恢复。1.备忘录模式通过Originator创建Memento对象来保存内部状态,确保只有Originator能访问和恢复该状态,从而保护封装性;2.Caretaker负责存储和传递Memento,但无法查看或修改其内容,实现了状态保存与业务逻辑的分离;3.该模式避免了直接复制对象或暴露成员变量带来的高耦合和复杂性,尤其适用于处理包含私有成员、指针或引用的复杂对象状态;4.使用时需注意内存消耗、深拷贝实现及性能开销,特别是频繁保存庞大

本文目录

    在C++中使用备忘录模式是为了在不破坏对象封装性的前提下实现状态的保存与恢复。1. 备忘录模式通过Originator创建Memento对象来保存内部状态,确保只有Originator能访问和恢复该状态,从而保护封装性;2. Caretaker负责存储和传递Memento,但无法查看或修改其内容,实现了状态保存与业务逻辑的分离;3. 该模式避免了直接复制对象或暴露成员变量带来的高耦合和复杂性,尤其适用于处理包含私有成员、指针或引用的复杂对象状态;4. 使用时需注意内存消耗、深拷贝实现及性能开销,特别是频繁保存庞大状态可能导致的问题;5. 除备忘录模式外,还可根据需求选择命令模式(适合操作撤销/重做)、序列化(适合持久化存储)或原型模式(适合简单对象复制)。

    怎样用C++实现备忘录模式 对象状态保存与恢复的实现

    备忘录模式(Memento Pattern)在C++中,核心思想就是允许你在不破坏对象封装性的前提下,捕获并保存一个对象的内部状态,以便在需要时将对象恢复到这个状态。这就像给对象拍了一张快照,随时可以“回溯”到那个时间点。

    怎样用C++实现备忘录模式 对象状态保存与恢复的实现
    #include 
    #include 
    #include 
    #include  // For std::shared_ptr
    
    // 1. Memento (备忘录) 类
    // 存储 Originator 的内部状态。通常,它只提供给 Originator 访问其状态的接口,
    // 而对 Caretaker 而言,它是一个不透明的对象。
    class Memento {
    private:
        std::string state_; // 存储的具体状态数据
    
        // 允许 Originator 访问 Memento 的私有状态
        friend class Originator;
    
        // 私有构造函数,确保只有 Originator 能创建 Memento
        Memento(const std::string& state) : state_(state) {
            // std::cout << "Memento created with state: " << state_ << std::endl;
        }
    
    public:
        // Caretaker 可以通过这个接口获取 Memento 的一些元信息,
        // 但不能直接修改其内部状态
        std::string GetName() const {
            // 实际应用中可能返回时间戳或版本号
            return "State_" + state_.substr(0, 5) + "...";
        }
    
        // 析构函数,如果内部有动态资源需要释放
        ~Memento() {
            // std::cout << "Memento for state '" << state_ << "' destroyed." << std::endl;
        }
    };
    
    // 2. Originator (发起人) 类
    // 拥有一个需要被保存和恢复状态的对象。
    // 它负责创建 Memento 并使用 Memento 恢复其内部状态。
    class Originator {
    private:
        std::string state_; // Originator 的当前状态
    
    public:
        Originator(const std::string& state) : state_(state) {
            std::cout << "Originator: Initializing with state: " << state_ << std::endl;
        }
    
        void DoSomething() {
            // 模拟 Originator 进行一些操作,改变自身状态
            static int counter = 0;
            state_ = "State_" + std::to_string(counter++) + "_doing_something_important";
            std::cout << "Originator: Changed state to: " << state_ << std::endl;
        }
    
        // 创建一个 Memento 来保存当前状态
        std::shared_ptr Save() {
            std::cout << "Originator: Saving current state to Memento." << std::endl;
            return std::make_shared(state_);
        }
    
        // 从 Memento 恢复状态
        void Restore(std::shared_ptr memento) {
            if (memento) {
                state_ = memento->state_; // 直接访问 Memento 的私有状态
                std::cout << "Originator: Restoring state to: " << state_ << std::endl;
            } else {
                std::cout << "Originator: Cannot restore from a null Memento." << std::endl;
            }
        }
    
        void ShowState() const {
            std::cout << "Originator: Current state is: " << state_ << std::endl;
        }
    };
    
    // 3. Caretaker (负责人) 类
    // 负责保存 Memento 对象,但从不检查或修改 Memento 的内容。
    // 它只知道 Memento 是一个可以被保存和检索的对象。
    class Caretaker {
    private:
        std::vector> mementos_; // 存储 Memento 对象的集合
        std::shared_ptr originator_;         // 持有 Originator 的引用
    
    public:
        Caretaker(std::shared_ptr originator) : originator_(originator) {}
    
        void Backup() {
            std::cout << "\nCaretaker: Saving Originator's state..." << std::endl;
            mementos_.push_back(originator_->Save());
        }
    
        void Undo() {
            if (mementos_.empty()) {
                std::cout << "\nCaretaker: No mementos to restore from." << std::endl;
                return;
            }
    
            std::shared_ptr memento = mementos_.back();
            mementos_.pop_back();
            std::cout << "\nCaretaker: Restoring state to: " << memento->GetName() << std::endl;
            originator_->Restore(memento);
        }
    
        void ShowHistory() const {
            std::cout << "\nCaretaker: Here's the list of mementos:" << std::endl;
            for (const auto& memento : mementos_) {
                std::cout << " - " << memento->GetName() << std::endl;
            }
        }
    };
    
    // 客户端代码示例
    int main() {
        auto originator = std::make_shared("Initial State");
        auto caretaker = std::make_unique(originator);
    
        caretaker->Backup(); // 保存初始状态
        originator->DoSomething();
        originator->ShowState();
    
        caretaker->Backup(); // 保存新状态
        originator->DoSomething();
        originator->ShowState();
    
        caretaker->Backup(); // 保存再一个新状态
        originator->DoSomething();
        originator->ShowState();
    
        caretaker->ShowHistory();
    
        std::cout << "\n--- Performing Undo operations ---" << std::endl;
        caretaker->Undo(); // 恢复到上一个状态
        originator->ShowState();
    
        caretaker->Undo(); // 恢复到再上一个状态
        originator->ShowState();
    
        caretaker->Undo(); // 恢复到初始状态
        originator->ShowState();
    
        caretaker->Undo(); // 尝试恢复,但没有更多备忘录了
    
        return 0;
    }

    为什么在C++中要用备忘录模式?

    我第一次接触到“状态保存与恢复”的需求时,脑子里最直接的想法就是直接复制对象,或者把对象的所有成员变量都暴露出来,然后手动赋值。但很快我就发现,这简直是个灾难。尤其是在C++这种强调封装的语言里,直接暴露内部状态不仅违反了面向对象的基本原则,更可能导致代码耦合度极高,难以维护。想象一下,如果一个对象的内部状态很复杂,包含各种私有成员、指针甚至其他对象的引用,你如何确保复制的完整性和正确性?手动处理深拷贝简直是噩梦。

    怎样用C++实现备忘录模式 对象状态保存与恢复的实现

    备忘录模式恰好解决了这个痛点。它巧妙地将“保存状态”的职责委托给对象自身(Originator),让它生成一个“备忘录”(Memento),这个备忘录对外部(Caretaker)来说是完全不透明的,你只能存储和传递它,而不能窥探或修改它的内容。只有Originator自己知道如何从备忘录中恢复状态。这就像你把一个加密的保险箱钥匙交给了Originator,只有它能打开并取出里面的东西,而Caretaker只是帮你保管这个保险箱。这种设计极大地保护了封装性,让状态的保存和恢复变得既安全又优雅。对我来说,它不仅仅是一种设计模式,更是一种对“责任分离”原则的深刻实践。

    备忘录模式的潜在挑战和注意事项是什么?

    在我实际应用备忘录模式的过程中,也踩过一些坑,积累了一些经验。最常见的挑战之一就是备忘录的内存消耗。如果你的Originator对象状态非常庞大,或者你需要频繁地创建备忘录(比如实现一个深度很大的撤销/重做功能),那么存储大量的备忘录可能会迅速耗尽内存。我曾遇到过一个图形编辑器项目,每一步操作都生成一个完整的画布状态备忘录,结果几分钟操作下来,程序就因为内存溢出崩溃了。

    怎样用C++实现备忘录模式 对象状态保存与恢复的实现

    另一个棘手的问题是深拷贝与浅拷贝。如果Originator的状态包含指针或动态分配的资源,那么在创建备忘录时,你必须确保执行的是深拷贝,而不是简单地复制指针地址。否则,当Originator或备忘录被销毁时,可能会导致内存泄漏或双重释放的错误。这要求Originator在创建Memento时,对内部复杂数据结构的处理要格外小心,确保所有资源都被正确地复制到备忘录中。

    最后,性能开销也是一个需要考虑的因素。创建和恢复备忘录可能涉及大量的内存分配、数据复制和销毁操作。在高性能要求的应用中,频繁地使用备忘录模式可能会引入不可接受的延迟。这时候,可能需要考虑优化策略,比如只保存状态的增量变化(Delta Memento),或者限制备忘录的数量。这让我头疼了一阵子,最终我们不得不权衡功能完整性和性能之间的平衡。

    除了备忘录模式,还有哪些实现对象状态保存与恢复的方案?

    有时候,我会问自己,是不是所有需要状态恢复的场景都非得用备忘录模式不可?答案显然不是。根据具体的需求和场景,我们还有其他一些选择,它们各有优缺点:

    1. 命令模式(Command Pattern): 这是一个非常强大的模式,尤其适合实现撤销/重做功能。与备忘录模式关注“状态”不同,命令模式关注“操作”。每一个用户操作都被封装成一个命令对象,这个命令对象知道如何执行自己,也知道如何撤销自己。通过维护一个命令历史列表,就可以实现复杂的撤销和重做。我发现,在很多交互式应用中,命令模式比备忘录模式更灵活,因为它不仅能恢复状态,还能重放操作序列,但它的缺点是每个命令都需要实现撤销逻辑,这会增加代码量。

    2. 序列化(Serialization): 如果你的主要目标是持久化对象状态,例如将对象保存到文件、数据库或通过网络传输,那么序列化是更直接的选择。C++本身没有内置的序列化机制,但有很多第三方库(如Boost.Serialization, Cereal, Protobuf等)可以实现。序列化将对象的状态转换为字节流,然后可以从字节流中重建对象。这与备忘录模式的短期内存管理不同,它更侧重于长期存储和跨进程/系统的数据交换。

    3. 原型模式(Prototype Pattern): 当你需要创建大量相似对象,并且这些对象的创建成本很高时,原型模式很有用。它通过克隆现有对象来创建新对象。如果你的“状态保存”只是简单地复制一个对象的当前完整状态,并且这个对象没有复杂的内部结构(比如不包含裸指针),那么简单的深拷贝配合原型模式可能就足够了,而无需引入备忘录模式的复杂性。它避免了备忘录模式中 Originator 和 Memento 之间的耦合,但牺牲了对内部状态的封装性。

    选择哪种方案,最终还是取决于你的具体需求:是需要精细的封装和回滚能力?是需要长期持久化?还是仅仅需要简单的对象复制?我通常会根据这些问题来做决策。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw macOS版
    AionClaw macOS版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy macOS版
    Loomy macOS版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirBuddy 3 macOS版
    AirBuddy 3 macOS版

    AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

    AirServer macOS版
    AirServer macOS版

    AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

    AnyDesk macOS版
    AnyDesk macOS版

    AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。

    讯飞绘文 网页版
    讯飞绘文 网页版

    讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

    Maya(Autodesk Maya) Windows版
    Maya(Autodesk Maya) Windows版

    Autodesk Maya 是面向影视、电视、动画和游戏行业的专业三维制作软件,集多边形与 NURBS 建模、角色绑定、关键帧和动作捕捉动画、Bifrost 特效模拟、材质开发及 Arnold 渲染于一体,

    Aperty Windows版
    Aperty Windows版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw Windows版
    AionClaw Windows版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy Windows版
    Loomy Windows版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。