全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

C++如何实现一个备忘录模式_C++在不破坏封装性的前提下捕获并恢复一个对象的内部状态

备忘录模式通过发起人、备忘录和管理者三者协作,在不破坏封装性的前提下实现状态保存与恢复;发起人创建并恢复状态,备忘录由发起人私有嵌套定义以保护内部数据,管理者仅负责存储和传递备忘录指针,无法访问其内容,从而确保安全性与封装性。

在C++中实现备忘录模式,核心目标是在不破坏封装性的前提下捕获并恢复一个对象的内部状态。这个模式常用于实现撤销(undo)功能、状态快照或事务回滚等场景。关键是将状态保存与恢复逻辑分离,避免暴露对象的私有成员。

备忘录模式的基本角色

备忘录模式包含三个主要角色:

  • 发起人(Originator):拥有内部状态的对象,能创建备忘录来保存当前状态,也能通过备忘录恢复状态。
  • 备忘录(Memento):负责存储发起人的内部状态。通常设计为发起人的嵌套类或友元类,以访问其私有成员,但对外部只提供有限接口。
  • 管理者(Caretaker):负责保存和管理备忘录对象,但不能访问或修改备忘录中的状态数据。

使用嵌套类和友元实现封装

为了不破坏封装性,可以将备忘录类定义为发起人的私有嵌套类,并允许管理者通过指针或引用间接持有它。这样外部无法直接构造或访问状态字段。

#include 
#include 
#include 

class Originator { private: std::string state;

// 私有嵌套类作为备忘录
class Memento {
    friend class Originator; // 允许Originator访问私有成员
private:
    std::string savedState;
    Memento(const std::string& s) : savedState(s) {}
public:
    const std::string& getState() const { return savedState; }
};

public: void setState(const std::string& s) { state = s; std::cout

std::string getState() const {
    return state;
}

// 创建备忘录
Memento* saveToMemento() const {
    return new Memento(state);
}

// 从备忘录恢复状态
void restoreFromMemento(Memento* m) {
    if (m) {
        state = m-youjiankuohaophpcngetState();
        std::cout zuojiankuohaophpcnzuojiankuohaophpcn "State restored to: " zuojiankuohaophpcnzuojiankuohaophpcn state zuojiankuohaophpcnzuojiankuohaophpcn "\n";
    }
}

};

// 管理者:保存和管理多个备忘录(如用于撤销栈) class Caretaker { private: std::stack<:memento> history;

public: void push(Originator::Memento* m) { history.push(m); }

Originator::Memento* pop() {
    if (history.empty()) return nullptr;
    Originator::Memento* m = history.top();
    history.pop();
    return m;
}

~Caretaker() {
    while (!history.empty()) {
        delete history.top();
        history.pop();
    }
}

};

实际使用示例

下面演示如何用该模式实现简单的撤销操作:

int main() {
    Originator originator;
    Caretaker caretaker;
originator.setState("State1");
caretaker.push(originator.saveToMemento());

originator.setState("State2");
caretaker.push(originator.saveToMemento());

originator.setState("State3");

// 撤销一次
Originator::Memento* m = caretaker.pop();
originator.restoreFromMemento(m);
delete m; // 可选:由Caretaker统一管理时可省略

// 再撤销一次
m = caretaker.pop();
originator.restoreFromMemento(m);

return 0;

}

关键设计要点

要真正保证封装性和安全性,需注意以下几点:

  • 备忘录类应为发起人的私有类,防止外部构造或篡改。
  • 管理者只能持有和传递备忘录指针,不能访问其内容。
  • 使用智能指针(如std::unique_ptr)可更好管理生命周期,避免内存泄漏。
  • 若状态较大,考虑深拷贝或共享数据(如使用copy-on-write)优化性能。

基本上就这些。这种实现方式既保护了对象的私有状态,又实现了灵活的状态保存与恢复机制。


#   # ai  # c++  # ios  # stream  # 封装性  # red  # String  # 封装  # const  # void  # 指针  # 接口  # class  # public  # private  # copy  # 对象  # history  # 前提下  # 多个  # 也能  # 几点  # 可选  # 但对  # 只提供  # 如何用  # 需注意  # 实现了 


相关文章: 如何快速搭建二级域名独立网站?  成都网站制作公司哪家好,四川省职工服务网是做什么用?  如何用AWS免费套餐快速搭建高效网站?  矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?  如何高效配置香港服务器实现快速建站?  湖州网站制作公司有哪些,浙江中蓝新能源公司官网?  建站之星手机一键生成:多端自适应+小程序开发快速建站指南  云南网站制作公司有哪些,云南最好的招聘网站是哪个?  头像制作网站在线制作软件,dw网页背景图像怎么设置?  桂林网站制作公司有哪些,桂林马拉松怎么报名?  如何在新浪SAE免费搭建个人博客?  ppt在线制作免费网站推荐,有什么下载免费的ppt模板网站?  阿里云高弹*务器配置方案|支持分布式架构与多节点部署  如何通过网站建站时间优化SEO与用户体验?  制作网站的公司有哪些,做一个公司网站要多少钱?  公司网站制作价格怎么算,公司办个官网需要多少钱?  如何在云主机上快速搭建多站点网站?  代购小票制作网站有哪些,购物小票的简要说明?  黑客入侵网站服务器的常见手法有哪些?  昆明网站制作哪家好,昆明公租房申请网上登录入口?  北京网站制作的公司有哪些,北京白云观官方网站?  如何快速查询域名建站关键信息?  模具网站制作流程,如何找模具客户?  简单实现Android文件上传  网站专业制作公司有哪些,做一个公司网站要多少钱?  建站中国必看指南:CMS建站系统+手机网站搭建核心技巧解析  c++怎么编写动态链接库dll_c++ __declspec(dllexport)导出与调用【方法】  图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?  官网自助建站平台指南:在线制作、快速建站与模板选择全解析  高防服务器租用指南:配置选择与快速部署攻略  c# F# 的 MailboxProcessor 和 C# 的 Actor 模型  如何选择建站程序?包含哪些必备功能与类型?  如何快速搭建安全的FTP站点?  如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?  清除minerd进程的简单方法  网站制作知乎推荐,想做自己的网站用什么工具比较好?  建站之星导航如何优化提升用户体验?  建站DNS解析失败?如何正确配置域名服务器?  html制作网站的步骤有哪些,iapp如何添加网页?  专业公司网站制作公司,用什么语言做企业网站比较好?  如何快速建站并高效导出源代码?  建站之星代理商如何保障技术支持与售后服务?  网站制作公司,橙子建站是合法的吗?  微信小程序制作网站有哪些,微信小程序需要做网站吗?  打鱼网站制作软件,波克捕鱼官方号怎么注册?  Android自定义控件实现温度旋转按钮效果  制作旅游网站html,怎样注册旅游网站?  极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?  定制建站流程解析:需求评估与SEO优化功能开发指南  如何注册花生壳免费域名并搭建个人网站? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。