《C++新经典设计模式》之第18章 备忘录模式
《C++新经典设计模式》之第18章 备忘录模式
- 备忘录模式.cpp
备忘录模式.cpp
#include <iostream>
#include <vector>
#include <memory>
using namespace std;// 保存对象内部状态,必要时恢复
// 在不破坏封装性的前提下,捕获对象的内部状态并保存,之后可将对象恢复到原先保存的状态
// 3种角色
// Originator(原发器),普通业务类,可以创建备忘录用于保存其当前的内部状态,之后用备忘录恢复内部状态
// Memento(备忘录),存储原发器对象某个瞬间的内部状态
// CareTaker(负责人/管理者),保存和传递备忘录,不知道备忘录细节,不能检查或操作备忘录namespace ns1
{class FighterMemento // 玩家主角相关的备忘录类{friend class Fighter; // 友元类Fighter可以访问本类的私有成员函数// 玩家主角类中要保存起来的数据,就放到这里来int m_life; // 生命值int m_magic; // 魔法值int m_attack; // 攻击力private: // 构造函数,用private修饰以防止在外部被随意创建FighterMemento(int life, int magic, int attack) : m_life(life), m_magic(magic), m_attack(attack) {}private: // 提供一些供Fighter类来访问的接口,用private修饰防止被任意类访问int getLife() const { return m_life; }void setLife(int life) { m_life = life; }int getMagic() const { return m_magic; }void setMagic(int magic) { m_magic = magic; }int getAttack() const { return m_attack; }void setAttack(int attack) { m_attack = attack; }};class Fighter // 玩家主角类{ // 角色属性int m_life; // 生命值int m_magic; // 魔法值int m_attack; // 攻击力public:Fighter(int life, int magic, int attack) : m_life(life), m_magic(magic), m_attack(attack) {}public: // 将玩家数据写入备忘录(创建备忘录,并在其中存储了当前状态)shared_ptr<FighterMemento> createMomento() const{shared_ptr<FighterMemento> back(new FighterMemento(m_life, m_magic, m_attack));return back;// return make_shared<FighterMemento>(m_life, m_magic, m_attack);}void restoreMomento(const shared_ptr<FighterMemento> &pfm) // 从备忘录中恢复玩家数据{m_life = pfm->m_life; // 友元类m_magic = pfm->getMagic();m_attack = pfm->getAttack();}void setToDead() { m_life = 0; } // 为测试目的引入的接口,设置玩家的生命值为0(玩家死亡)void displayInfo() const // 用于输出一些信息{cout << "The player's current HP, magic and attack power are respectively " << m_life << ", " << m_magic << ", " << m_attack << endl;}};class FCareTaker // 管理者(负责人)类{shared_ptr<FighterMemento> m_pfm; // 指向备忘录对象的指针public:FCareTaker(const shared_ptr<FighterMemento> &ptmpfm = nullptr) : m_pfm(ptmpfm) {} // 形参是指向备忘录对象的指针shared_ptr<FighterMemento> getMemento() const { return m_pfm; } // 获取指向备忘录对象的指针void setMemento(const shared_ptr<FighterMemento> &ptmpfm) { m_pfm = ptmpfm; } // 保存指向备忘录对象的指针};class FCareTaker2 // 支持多个快照的负责人(管理者)类{vector<shared_ptr<FighterMemento>> m_pfmContainer; // 存储备忘录对象指针的容器public:void push(const shared_ptr<FighterMemento> &ptmpfm) { m_pfmContainer.emplace_back(ptmpfm); } // 保存指向备忘录对象的指针shared_ptr<FighterMemento> pop(){if (m_pfmContainer.empty())return nullptr;return m_pfmContainer.back();}shared_ptr<FighterMemento> getMemento(int index) const // 获取指向备忘录对象的指针{if (index >= 0 && index < m_pfmContainer.size())return m_pfmContainer[index];return nullptr;}};
}int main()
{
#if 0using namespace ns1;shared_ptr<Fighter> p_fighter(new Fighter(800, 200, 300));// (1)显示玩家主角在与BOSS战斗之前的信息p_fighter->displayInfo();// (2)为玩家主角类对象创建一个备忘录对象(其中保存了当前主角类对象中的必要信息)shared_ptr<FighterMemento> p_fighterMemo = p_fighter->createMomento();// (3)玩家与BOSS开始战斗cout << "The protagonist of the player and BOSS began to fight fiercely------" << endl;p_fighter->setToDead(); // 玩家主角在与BOSS战斗中,生命值最终变成0而死亡(被BOSS击败)p_fighter->displayInfo(); // 显示玩家主角在与BOSS战斗之后的信息// (4)因为在与BOSS战斗之前已经通过NPC保存了游戏进度,这里模拟载入游戏进度,恢复玩家主角类对象的数据,让其可以与BOSS再次战斗cout << "Players recover their information through memos------" << endl;p_fighter->restoreMomento(p_fighterMemo);p_fighter->displayInfo(); // 显示玩家主角通过备忘录恢复到战斗之前的信息
#endif#if 0using namespace ns1;shared_ptr<Fighter> p_fighter(new Fighter(800, 200, 300));// (1)显示玩家主角在与BOSS战斗之前的信息p_fighter->displayInfo();// (2)为玩家主角类对象创建一个备忘录对象(其中保存了当前主角类对象中的必要信息)shared_ptr<FCareTaker> pfcaretaker(new FCareTaker(p_fighter->createMomento()));// (3)玩家与BOSS开始战斗cout << "The protagonist of the player and BOSS began to fight fiercely------" << endl;p_fighter->setToDead(); // 玩家主角在与BOSS战斗中,生命值最终变成0而死亡(被BOSS击败)p_fighter->displayInfo(); // 显示玩家主角在与BOSS战斗之后的信息// (4)因为在与BOSS战斗之前已经通过NPC保存了游戏进度,这里模拟载入游戏进度,恢复玩家主角类对象的数据,让其可以与BOSS再次战斗cout << "Players recover their information through memos------" << endl;p_fighter->restoreMomento(pfcaretaker->getMemento());p_fighter->displayInfo(); // 显示玩家主角通过备忘录恢复到战斗之前的信息
#endif#if 1using namespace ns1;shared_ptr<Fighter> p_fighter2(new Fighter(800, 200, 300));shared_ptr<FCareTaker2> pfcaretaker2(new FCareTaker2());pfcaretaker2->push(p_fighter2->createMomento()); // 做第一次快照吗,此快照玩家生命值为800p_fighter2->setToDead(); // 改变玩家主角的生命值pfcaretaker2->push(p_fighter2->createMomento()); // 做第二次快照,此快照玩家生命值为0p_fighter2->displayInfo(); // 玩家主角生命值应该为0cout << "------------------" << endl;// 当前玩家生命值为0,恢复第一次快照,也就是恢复玩家生命值为800p_fighter2->restoreMomento(pfcaretaker2->getMemento(0));p_fighter2->displayInfo(); // 玩家主角生命值应该恢复为800
#endifcout << "Over!\n";return 0;
}
相关文章:
《C++新经典设计模式》之第18章 备忘录模式
《C新经典设计模式》之第18章 备忘录模式 备忘录模式.cpp 备忘录模式.cpp #include <iostream> #include <vector> #include <memory> using namespace std;// 保存对象内部状态,必要时恢复 // 在不破坏封装性的前提下,捕获对象的内部…...
OWASP安全练习靶场juice shop-更新中
Juice Shop是用Node.js,Express和Angular编写的。这是第一个 完全用 JavaScript 编写的应用程序,列在 OWASP VWA 目录中。 该应用程序包含大量不同的黑客挑战 用户应该利用底层的困难 漏洞。黑客攻击进度在记分板上跟踪。 找到这个记分牌实际上是&#…...
当使用RSA加密,从手机前端到服务器后端的请求数据存在+
将转成了空格,导致解密出错 将空格转成了...
BUUCTF crypto做题记录(3)新手向
目录 一、Rabbit 二、篱笆墙的影子 三、丢失的MD5 四、Alice与Bob 一、Rabbit 得到的密文:U2FsdGVkX1/ydnDPowGbjjJXhZxm2MP2AgI 依旧是看不懂是什么编码,上网搜索,在侧栏发现Rabbit解码,直接搜索就能有在线解码网站 二、篱笆…...
SpringMVC修炼之旅(2)基础入门
一、第一个程序 1.1环境配置 略 1.2代码实现 package com.itheima.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;//定义…...
matlab 最小二乘拟合空间直线(方法二)
目录 一、算法原理1、算法过程2、参考文献二、代码实现三、结果展示四、相关链接本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理...
ASPICE-汽车软件开发能力评级
Automotive SPICE(简称A-SPICE 或 ASPICE),全称是“Automotive Software Process Improvement and Capacity dEtermination”,即“汽车软件过程改进及能力评定”模型框架。 常被用于评估一家汽车软件供应商的软件开发能力&#x…...
准确!!!在 CentOS 8 上配置 PostgreSQL 14 的主从复制
在 CentOS 8 上配置 PostgreSQL 14 的主从复制,并设置 WAL 归档到特定路径 /home/postgres/archive 的步骤如下: 主服务器配置(主机) 配置 PostgreSQL: 编辑 postgresql.conf 文件: vim /data/postgres/p…...
leetcode 1466
leetcode 1466 使用dfs 遍历图结构 如图 node 4 -> node 0 -> node 1 因为节点数是n, 边长数量是n-1。所以如果是从0出发的路线,都需要修改,反之,如果是通向0的节点,例如节点4,则把节点4当作父节点的节点&…...
想学编程,但不知道从哪里学起,应该怎么办?
怎样学习任何一种编程语言 我将教你怎样学习任何一种你将来可能要学习的编程语言。本书的章节是基于我和很多程序员学习编程的经历组织的,下面是我通常遵循的流程。 1.找到关于这种编程语言的书或介绍性读物。 2.通读这本书,把…...
Python数据科学视频讲解:Python概述
2.1 Python概述 视频为《Python数据科学应用从入门到精通》张甜 杨维忠 清华大学出版社一书的随书赠送视频讲解2.1节内容。本书已正式出版上市,当当、京东、淘宝等平台热销中,搜索书名即可。内容涵盖数据科学应用的全流程,包括数据科学应用和…...
数据结构之内部排序
目录 7-1 直接插入排序 输入格式: 输出格式: 输入样例: 输出样例: 7-2 寻找大富翁 输入格式: 输出格式: 输入样例: 输出样例: 7-3 PAT排名汇总 输入格式: 输出格式: 输入样例: 输出样例: 7-4 点赞狂魔 输入格式: 输出格式: 输入样例&a…...
软考高级备考-系统架构师(机考后新版教材的备考过程与资料分享)
软考高级-系统架构设计师 考试复盘1.考试结果2.备考计划3.个人心得 资料分享 考试复盘 1.考试结果 三科压线过,真是太太太太太太太幸运了。上天对我如此眷顾,那不得不分享下我的备考过程以及一些备考资料,帮助更多小伙伴通过考试。 2.备考…...
Spring Boot 整合kafka:生产者ack机制和消费者AckMode消费模式、手动提交ACK
目录 生产者ack机制消费者ack模式手动提交ACK 生产者ack机制 Kafka 生产者的 ACK 机制指的是生产者在发送消息后,对消息副本的确认机制。ACK 机制可以帮助生产者确保消息被成功写入 Kafka 集群中的多个副本,并在需要时获取确认信息。 Kafka 提供了三种…...
Java+Swing: 主界面组件布局 整理9
说明:这篇博客是在上一篇的基础上的,因为上一篇已经将界面的框架搭好了,这篇主要是将里面的组件完善。 分为三个部分,北边的组件、中间的组件、南边的组件 // 放置北边的组件layoutNorth(contentPane);// 放置中间的 Jtablelayou…...
pytorch:YOLOV1的pytorch实现
pytorch:YOLOV1的pytorch实现 注:本篇仅为学习记录、学习笔记,请谨慎参考,如果有错误请评论指出。 参考: 动手学习深度学习pytorch版——从零开始实现YOLOv1 目标检测模型YOLO-V1损失函数详解 3.1 YOLO系列理论合集(Y…...
YOLOv8配置文件yolov8.yaml解读
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制 位置 该文件的位置位于 ./ultralytics/cfg/models/v8/yolov8.yaml 模型参数配置 # Parameters nc: 80 # number of classes scales: #…...
4-Tornado高并发原理
核心原理就是协程epoll事件循环,再使用协程之后,开销是特别的小,那具体如何提供高并发的呢? 异步非阻塞IO 这意味我们整套开发的模式不在与原来一样,正因为不再一样,所以有时我们在理解代码时就有可能会比…...
基于以太坊的智能合约开发Solidity(事件日志篇)
//声明版本号(程序中的版本号要和编译器版本号一致) pragma solidity ^0.5.17; //合约 contract EventTest {//状态变量uint public Variable;//构造函数constructor() public{Variable 100;}event ValueChanged(uint newValue); //事件声明event Log(…...
【BME2112】w11 notes
下周做老鼠实验 group analysis SPM group analysis 数据地址resting state 可以分析:correlation 计算两个脑区的相关性 静息态实验简单functional 成功的实验能看到激活区不成功的实验:比如被试头动太大,不是健康的被试 Spontaneous brain…...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...
