《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…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...
