新闻中心

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

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

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

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

备忘录模式的基本角色

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

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

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

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

#include <iostream>
#include <string>
#include <stack>
<p>class Originator {
private:
std::string state;</p><pre class='brush:php;toolbar:false;'>// 私有嵌套类作为备忘录
class Memento {
    friend class Originator; // 允许Originator访问私有成员
private:
    std::string s*edState;
    Memento(const std::string& s) : s*edState(s) {}
public:
    const std::string& getState() const { return s*edState; }
};

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

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

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

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

};

CA.LA CA.LA

第一款时尚产品在线设计平台,服装设计系统

CA.LA 94 查看详情 CA.LA

// 管理者:保存和管理多个备忘录(如用于撤销栈) 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;
<pre class='brush:php;toolbar:false;'>originator.setState("State1");
caretaker.push(originator.s*eToMemento());

originator.setState("State2");
caretaker.push(originator.s*eToMemento());

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)优化性能。

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

以上就是C++如何实现一个备忘录模式_C++在不破坏封装性的前提下捕获并恢复一个对象的内部状态的详细内容,更多请关注其它相关文章!


# 也能  # 医院市场营销推广策略  # 快排seo收费贵吗  # seo关键词排名佰金手指六六二八  # 网站建设思路方案模板  # 企业网站建设的论坛  # 汕尾商城网站推广多少钱  # 淮南网站推广选哪家好点  # 白山抖音seo优化方案  # seo长尾词扩展方法  # 荆州工程机械网站推广  # 解决问题  # 中文网  # 相关文章  #   # 多个  # 多态  # 调试器  # 前提下  # 如何使用  # 如何实现  # red  # 封装性  # stream  # ios  # c++  # ai 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 新手怎么开始学化妆 零基础化妆入门教程  Eclipse怎么运行工程_Eclipse工程运行配置说明  word邮件合并后日期格式不对怎么改_Word邮件合并日期格式修改方法  AO3官方在线访问地址 Archive of Our Own最新镜像合集  4399免费游戏网址入口 4399小游戏免费入口点开即玩  消息称三星明年 2 月正式发布 HBM4,与 SK 海力士同台竞技  文本文档写html代码怎么运行_文本文档html代码运行步骤【教程】  Win11怎么修改默认浏览器_Windows 11设置Chrome为默认  4399体育竞技小游戏_4399小游戏赛事入口  CSS图片焦点样式实现教程:理解与应用tabindex属性  动漫岛观看全网网 动漫岛在线正版动漫入口  极速漫画官方主页网址 极速漫画漫画在线浏览官网链接  微信网页版登录教程_微信网页版登录入口在哪  outlook中文官网入口地址 outlook官方中文版直达首页链接  LINUX怎么设置定时任务_LINUX crontab配置教程  Go语言中的*string:深入理解字符串指针  曝R星经典之作开发图 设计简陋但信息密集!  Golang切片为何属于引用类型_Golang slice底层结构与引用语义说明  文心一言怎样用批量生成做多版文案_文心一言用批量生成做多版文案【批量创作】  NVIDIA股价11月重挫12%:下月有望好转 但难回5万亿美元巅峰  想当下一个《2077》?《心之眼》Steam评价升至"多半好评"  Win11怎么关闭快速启动_Win11彻底关机设置教程  126邮箱网页版官方入口 126邮箱账号在线登录平台  HuggingFaceEmbeddings中向量嵌入维度调整的限制与理解  Composer如何在生产环境安全地执行composer update  c++ 命名空间怎么用 c++ namespace使用指南  Win11怎么开启高性能模式_Windows 11电源计划优化设置  QQ邮箱登录首页官网地址2026 QQ邮箱官方网页入口  如何为你的Composer包编写自动化测试_集成PHPUnit到Composer的scripts工作流  4399网页游戏电脑版全新入口 4399电脑端在线玩指南  J*a中实现Go语言select通道多路复用机制  必由学官网首页入口 必由学教师网页版登录指南  sublime如何配置Go语言开发环境_sublime搭建Golang编译运行系统  2306选座时如何选靠窗位置_12306选座靠窗座位查看方法解析  谷歌浏览器如何快速清除某个网站的数据_Chrome网站缓存清理方法  Lar*el用户头像管理:实现图片缩放、存储与旧文件安全删除的最佳实践  Golang如何安装Swagger工具_GoSwagger文档生成环境  J*aScript中在Map循环中检测并处理空数组元素  J*a应用程序首次运行自动创建文件与目录的最佳实践  ExcelARRAYTOTEXT函数怎么自定义分隔符输出数组文本_ARRAYTOTEXT实现动态生成SQL语句  Win11输入法不见了怎么办_Windows11恢复语言栏显示方法  怎样把文件彻底粉碎无法恢复_Windows下安全删除敏感数据【隐私保护】  格力空气能E5故障代码是什么情况_格力空气能E5代码解析与应对措施  Node.js CSV 数据处理:基于字段空值条件过滤整条记录的策略  处理嵌套交互式控件:前端可访问性指南  iwriter统一登录平台 iwrite账号密码登录页面  印象笔记如何设提醒任务防漏执行_印象笔记设提醒任务防漏执行【任务提醒】  CSS Grid如何控制元素对齐_align-items与justify-items组合使用  动漫花园资源网使用步骤_动漫花园资源网下载流程  台积电1.4nm工艺A14瞄准2028:10年来性能提升80% 

搜索